dreamcast.wiki dcwiki https://dreamcast.wiki/Dreamcast.wiki MediaWiki 1.39.3 first-letter Media Special Talk User User talk DCWiki DCWiki talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Campaign Campaign talk Dreamcast.wiki 0 1 1 2020-01-09T22:04:21Z Unknown user 0 wikitext text/x-wiki <strong>MediaWiki has been installed.</strong> Consult the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents User's Guide] for information on using the wiki software. == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] 5702e4d5fd9173246331a889294caf01a3ad3706 2 1 2020-01-09T22:34:50Z Unknown user 0 wikitext text/x-wiki == Welcome to dreamcast.wiki == [[Development]] == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] 0ad95eb7f2df51b120fa16c688f7d309e0c20f80 18 2 2020-01-09T23:15:25Z Unknown user 0 wikitext text/x-wiki == Welcome to dreamcast.wiki == [[Development]] == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] == Repair == [[GD-ROM drive repair]] [[PSU repair]] [[Controller port repair]] [[Dreamcast case whitening]] == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] affbaaff2e2ee65584ade46a00464ce05325757d 19 18 2020-01-09T23:15:44Z Unknown user 0 /* Repair */ wikitext text/x-wiki == Welcome to dreamcast.wiki == [[Development]] == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] 970c21d9a4b38988cd4fcb802d482de5d15258eb 21 19 2020-01-09T23:19:16Z Unknown user 0 wikitext text/x-wiki = Welcome to dreamcast.wiki = == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] 9e9f0030d38c69789e15e829b20111ba315f4b4f 47 21 2020-01-09T23:43:57Z Unknown user 0 Add Dreamcast boot process page wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] 7ff8c49fd021f2ce614c2af3e9159c84d3402ba4 52 47 2020-01-09T23:50:11Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[DreamEye webcam]] ** [[Neo-Geo Pocket Color link cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] fb7274dde99a195352a2d50870b14e26ede41547 53 52 2020-01-09T23:51:23Z Unknown user 0 wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[DreamEye webcam]] ** [[Neo-Geo Pocket Color link cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening] b66fba9e8ebbfa45128da324685ccb9ccbec857a Development 0 2 3 2020-01-09T22:41:01Z Unknown user 0 Created page with "=== Getting started === * Linux * Win * MacOSX === Build & test === * Building your project * Emulators * Broadband Adapter * Serial * Disc === Graphics === * PVR * GLdc =..." wikitext text/x-wiki === Getting started === * Linux * Win * MacOSX === Build & test === * Building your project * Emulators * Broadband Adapter * Serial * Disc === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file 2347975068fb2956d90068f6389acb2575e9196b 4 3 2020-01-09T22:41:21Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Linux]] * Win * MacOSX === Build & test === * Building your project * Emulators * Broadband Adapter * Serial * Disc === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file af4efa7b2d47ac0cebcece28c881f90e09cb5306 5 4 2020-01-09T22:43:23Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win * MacOSX === Build & test === * Building your project * Emulators * Broadband Adapter * Serial * Disc === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file 9012d3b50dea65a3de35eea293c8a19d8a42dda3 9 5 2020-01-09T22:53:09Z Unknown user 0 /* Build & test */ wikitext text/x-wiki === Getting started === * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win * MacOSX === Build & test === * Building your project * [[Emulators]] * Broadband Adapter * Serial * Disc === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file 742f8515fb65588cb68b2ab8e7be22d075f4dcfc 12 9 2020-01-09T23:02:04Z Unknown user 0 wikitext text/x-wiki === Getting started === * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win * MacOSX === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR d54c9a9cb484a88c95bfcb29d55f2aae660cb8d6 17 12 2020-01-09T23:13:32Z Unknown user 0 wikitext text/x-wiki === Getting started === * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win * MacOSX === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR ce6d97dc194ab3ace6ea951551807f2399207b10 25 17 2020-01-09T23:24:23Z Unknown user 0 Add KOS WSL mention wikitext text/x-wiki === Getting started === * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * MacOSX === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR 649b8cbc3b5229917221861a0b4991413afb2f54 54 25 2020-01-09T23:52:01Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[KallistiOS - KOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * MacOSX === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * GLdc === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR 501aa9a23d7fce252b178435ab4fe655a3789b03 Dreamcast emulators 0 4 10 2020-01-09T22:53:43Z Unknown user 0 Created page with "== Reicast == == Redream == == NullDC == == LXdream ==" wikitext text/x-wiki == Reicast == == Redream == == NullDC == == LXdream == 0db0ac8293d41b97ae14cbe535df3de9ce34eadd 11 10 2020-01-09T22:56:26Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Reicast Official page : [https://reicast.com](https://reicast.com) Developed by : SKMP ### Supported feature ### Known issues ### Problems ## Redream ### Supported feature ### Known issues ### Problems ## NullDC ### Supported feature ### Known issues ### Problems ## LXdream ### Supported feature ### Known issues ### Problems 43e9584a95ca5d813316056d5506b61ac8c63246 15 11 2020-01-09T23:11:03Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast Official page : [https://reicast.com](https://reicast.com) Developed by : SKMP ### Supported feature ### Known issues ### Problems ## Redream ### Supported feature ### Known issues ### Problems ## NullDC ### Supported feature ### Known issues ### Problems ## LXdream ### Supported feature ### Known issues ### Problems cfbcae84ca314a055344a340a6ad131bf1ff1295 26 15 2020-01-09T23:26:05Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? ### Supported feature ### Known issues ### Problems ## Redream * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? ### Supported feature ### Known issues ### Problems ## NullDC * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? ### Supported feature ### Known issues ### Problems ## LXdream * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? ### Supported feature ### Known issues ### Problems 9a09eabefa917f4425d605753e6051d73340400d 34 26 2020-01-09T23:30:05Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? ### Supported feature ### Known issues ### Problems ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active ### Supported feature ### Known issues ### Problems ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp * Status : Inactive ### Supported feature ### Known issues ### Problems ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive ### Supported feature ### Known issues ### Problems d26baba2af11ada59f2d6337748f87ff1176df2c 36 34 2020-01-09T23:32:41Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? * Platform : Android, Windows ### Supported feature ### Known issues ### Problems ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues ### Problems ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ### Problems ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature ### Known issues ### Problems dd4d03d0ef8ea86de32c5fdbd0963018acc0b0e9 38 36 2020-01-09T23:35:17Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? * Platform : Android, Windows ### Supported feature ### Known issues ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - Console support (printf) ### Known issues 5684acaab0149db9db41e280cbe728ab71b8b7e5 Broadband adapter 0 5 13 2020-01-09T23:06:48Z Unknown user 0 Created page with "{{MARKDOWN}} ## BBA and dc-load-ip under Linux This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in..." wikitext text/x-wiki {{MARKDOWN}} ## BBA and dc-load-ip under Linux This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in between. ### Dreamcast side Get a selfbooting version of [dc-load-ip](http://download.sizious.com/dc/dctool/dcload-ip-1.0.4.7z). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code I'm currently using a [pre-compiled dcload-ip](http://napalm-x.thegypsy.com/adk/dc/dcload-ip/index.html) which seems to work fine. You can now use that program to send your file to the DC. Make sure you dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Arp The arp command used on step 3 will need to be entered every time you relog/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ 259b8e2816e30f697636c8a99e46fd518df470d2 14 13 2020-01-09T23:07:38Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## BBA and dc-load-ip under Linux This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in between. ### Dreamcast side Get a selfbooting version of [dc-load-ip](http://download.sizious.com/dc/dctool/dcload-ip-1.0.4.7z). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code I'm currently using a [pre-compiled dcload-ip](http://napalm-x.thegypsy.com/adk/dc/dcload-ip/index.html) which seems to work fine. You can now use that program to send your file to the DC. Make sure you dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ 7e1a39f0be8f70678999ae2f2b5fec99e0e44d44 16 14 2020-01-09T23:12:16Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dc-load-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in between. ### Dreamcast side Get a selfbooting version of [dc-load-ip](http://download.sizious.com/dc/dctool/dcload-ip-1.0.4.7z). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code I'm currently using a [pre-compiled dcload-ip](http://napalm-x.thegypsy.com/adk/dc/dcload-ip/index.html) which seems to work fine. You can now use that program to send your file to the DC. Make sure you dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ a1c0048e42357cdc863aabc3023072f085e95397 Dumping GD-ROMs 0 6 20 2020-01-09T23:18:14Z Unknown user 0 Created page with "Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be di..." wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. 1f2793a6c0e20470f65c35886a75a8ff56159510 23 20 2020-01-09T23:22:42Z Unknown user 0 add reference to httpd-ack for BBA wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a broadband adapter, the simplest way is using httpd-ack, which is available from here: https://www.gotwalls.com/ 4c473f20614bbe217811c5251c0009bf9a7eb647 GD-ROM 0 7 22 2020-01-09T23:19:34Z Unknown user 0 Created page with "The GD-ROM format is Sega's proprietary disc format used for the Sega Dreamcast home console, as well as for the arcade systems [[NAOMI]], [[NAOMI 2]], Triforce, and Chihiro." wikitext text/x-wiki The GD-ROM format is Sega's proprietary disc format used for the Sega Dreamcast home console, as well as for the arcade systems [[NAOMI]], [[NAOMI 2]], Triforce, and Chihiro. 715e424456764122903adcda3528aa7ae85fbbe7 A/V connectivity 0 8 24 2020-01-09T23:22:43Z Unknown user 0 Created page with "The Dreamcast natively supports RF video, composite video, S-video, 15KHz RGB video, and 31KHZ RGBHV ("VGA") output. Aftermarket cables containing circuits with YPbPr convers..." wikitext text/x-wiki The Dreamcast natively supports RF video, composite video, S-video, 15KHz RGB video, and 31KHZ RGBHV ("VGA") output. Aftermarket cables containing circuits with YPbPr conversion hardware can be purchased or created. The Dreamcast can also be [[DCHDMI|modified to support HDMI output]]. 1129245c3f39f6a082f34c71242af5d406b1e0bd 35 24 2020-01-09T23:31:06Z Unknown user 0 wikitext text/x-wiki The Dreamcast natively supports RF video, composite video, S-video, 15KHz RGB video ("RGB SCART"), and 31KHZ RGBHV ("VGA") output. The RGB mode and VGA mode do not work for all official game titles. See [[Video mode compatibility list|the compatibility list]] for more details. Aftermarket cables containing circuits with YPbPr conversion hardware can be purchased or created. The Dreamcast can also be [[DCHDMI|modified to support HDMI output]]. 2fdcea3f2f59265d6433c8d6d21887708ba8424f MediaWiki:Forums-url 8 9 27 2020-01-09T23:27:01Z Unknown user 0 Created page with "http://dcemulation.org/phpBB/" wikitext text/x-wiki http://dcemulation.org/phpBB/ 0aad0a17c5a9c485ceb334f8770232f49b274c0a MediaWiki:Sidebar 8 10 28 2020-01-09T23:27:13Z Unknown user 0 Created page with " * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SE..." wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES de97d7aaeddc8786eb4d29cc5504d9de6c70a901 29 28 2020-01-09T23:28:15Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** Hardware|Hardware ** Development|Development * wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES 8f01bf01b26f98dad7fee5824f2dc5b282cb9cb3 30 29 2020-01-09T23:28:33Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** Software|Software ** Hardware|Hardware ** Development|Development * wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES 5293908dcb49672729d3f5836d42f76037959fd7 32 30 2020-01-09T23:28:54Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** Software|Software ** Hardware|Hardware ** Development|Development ** Repair|Repair * wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES 738bcf27a33e864d97905f3da4350ad32bad6102 BIOS modification 0 12 39 2020-01-09T23:36:32Z Unknown user 0 Created page with "The Dreamcast's BIOS chip can be replaced (or a secondary chip added) to remove region checks, A/V connectivity compatibility checks, and add new features." wikitext text/x-wiki The Dreamcast's BIOS chip can be replaced (or a secondary chip added) to remove region checks, A/V connectivity compatibility checks, and add new features. 11d3230423ad368f6b582512e3b22d9a514d3da5 Indie games 0 13 40 2020-01-09T23:36:38Z Unknown user 0 Created page with "== Active Development == == Unknown Status == == Archive ==" wikitext text/x-wiki == Active Development == == Unknown Status == == Archive == 3d4a4936486d7534c291e9f02e5b64b20d8a3f9a 41 40 2020-01-09T23:37:04Z Unknown user 0 /* Active Development */ wikitext text/x-wiki == Active Development == * Summoning Signals == Unknown Status == == Archive == 923f988e3bc63b4a5ab8b9b52d50e9a2d3b4b90c 43 41 2020-01-09T23:40:10Z Unknown user 0 /* Active Development */ wikitext text/x-wiki == Active Development == * [[Rizzo Island]] - game description * [[Swirling Blades: Desert Thunder]] - Kazade's choplifter remix ;) * [[Summoning Signals]] - game description == Unknown Status == == Archive == f6f8fdc6caacd89bb637bf043f9366995d8b6b95 45 43 2020-01-09T23:41:12Z Unknown user 0 wikitext text/x-wiki == Active Development == * [[Rizzo Island]] - game description * [[Swirling Blades: Desert Thunder]] - Kazade's choplifter remix ;) * [[Summoning Signals]] - a strange poetic game with radio. == Unknown Status == == Archive == 911b844d7342349783a06e0b4702338a0a779df1 DCDigital 0 14 42 2020-01-09T23:40:08Z Unknown user 0 Created page with "DCHDMI is a modification kit created by chriz2600 and citrus3000psi which adds native HDMI output to the Sega Dreamcast." wikitext text/x-wiki DCHDMI is a modification kit created by chriz2600 and citrus3000psi which adds native HDMI output to the Sega Dreamcast. 9968474cf0080a48f5d7a5dd0933654cac808486 51 42 2020-01-09T23:48:45Z Unknown user 0 wikitext text/x-wiki DCHDMI is a modification kit created by chriz2600 and citrus3000psi which adds native HDMI output to the Sega Dreamcast. https://shop.dansprojects.com/dchdmi-pre-order.html 6fd1fe88b427b457bbcaea6daf534cc65defcb33 Serial SD card adapter 0 15 46 2020-01-09T23:42:30Z Unknown user 0 Created page with "The serial SD card adapter is a community-designed peripheral that allows software to access an SD card for reading and writing through the Dreamcast's serial connector. Files..." wikitext text/x-wiki The serial SD card adapter is a community-designed peripheral that allows software to access an SD card for reading and writing through the Dreamcast's serial connector. Files can be accessed and manipulated using [[DreamShell]]. Code and games can be executed from the SD card, but because access is limited by the slow serial connectivity, running commercial games in this way is typically slow and buggy. 15948a319cfef08177966a2d5002caf34e16506c Optical drive replacements 0 16 48 2020-01-09T23:45:18Z Unknown user 0 Created page with "An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices ty..." wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Examples include: * GDEMU * USB-GDROM * iceGDROM 6015d3a77c1b335c5aee32e67cca18fac77daeb9 Summoning Signals 0 17 49 2020-01-09T23:47:32Z Unknown user 0 Created page with "{{MARKDOWN}} ## Description -- insert game description -- **Type** : Artgame - Puzzle - ??? **Website** : [https://www.patreon.com/12dbsoft] **Release Date** : 2020 ##..." wikitext text/x-wiki {{MARKDOWN}} ## Description -- insert game description -- **Type** : Artgame - Puzzle - ??? **Website** : [https://www.patreon.com/12dbsoft] **Release Date** : 2020 ## Technical * 2D high resolution sprites using [[GLdc]] * Main engine in C. Game code is in LUA. 9428a281824b46c7e890d1812d41e0a45f8c96e6 DreamPi 0 18 50 2020-01-09T23:48:44Z Unknown user 0 Created page with "DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network. Using DreamPi can be preferred to a Broadband..." wikitext text/x-wiki DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. 41f8343bd92559f2b46f6c16baec266b37d61425 System Disc 2 0 19 55 2020-01-09T23:54:20Z Unknown user 0 Created page with "The Dreamcast System Disc 2 is a unique disc which, upon being read by the [[GD-ROM drive]], will unlock the Dreamcast's [[GD-ROM]] media security check, allowing one to acces..." wikitext text/x-wiki The Dreamcast System Disc 2 is a unique disc which, upon being read by the [[GD-ROM drive]], will unlock the Dreamcast's [[GD-ROM]] media security check, allowing one to access and play games on [[GD-R]] media. 7faa07296ceaedff14cb1320252b71dfb954f003 Boot process 0 20 56 2020-01-10T00:02:15Z Unknown user 0 Created page with "In general, the boot process is something like this:<br> <br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # IP.BIN is loaded to 0x8..." wikitext text/x-wiki In general, the boot process is something like this:<br> <br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # IP.BIN is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast unscrambles it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as DCLOAD-IP or DCLOAD-SERIAL bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL such that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. 9c0d48f999f96ad93d2271bd7c13c93bf2fd5adc 57 56 2020-01-10T00:02:49Z Unknown user 0 wikitext text/x-wiki In general, the boot process is something like this:<br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # IP.BIN is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast unscrambles it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as DCLOAD-IP or DCLOAD-SERIAL bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL such that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. 333ce32e0962c1f2d7fe44ef8e130708f1c550a3 Boot process 0 20 58 57 2020-01-10T00:03:36Z Unknown user 0 wikitext text/x-wiki In general, the boot process is something like this:<br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # IP.BIN is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast unscrambles it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as DCLOAD-IP or DCLOAD-SERIAL bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL so that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. 4d689d7c7254d986ebb396a42e3b8562c1c0d319 60 58 2020-01-10T00:05:40Z Unknown user 0 wikitext text/x-wiki In general, the boot process is something like this:<br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # [[IP.BIN]] is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast unscrambles it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as [[DCLOAD-IP]] or [[DCLOAD-SERIAL]] bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL so that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. ab7fb5c24c2687003ecaf96123542b2d70b3f270 92 60 2020-01-10T02:02:06Z Unknown user 0 wikitext text/x-wiki In general, the boot process is something like this:<br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # [[IP.BIN]] is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast scramble loads this binary from disc it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as [[DCLOAD-IP]] or [[DCLOAD-SERIAL]] bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL so that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. 66afa325ae198a4f34fd03da253165c7c5e8cb09 KallistiOS 0 21 59 2020-01-10T00:05:07Z Unknown user 0 Created page with "* Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) i..." wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Dan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of libdream, the first free developer library for Dreamcast. Libdream was also written by Dan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] d40783b53e1b38203682b5b6ee20f1904dd7b868 Indie games 0 13 61 45 2020-01-10T00:06:21Z Unknown user 0 wikitext text/x-wiki == Active Development == * [[Rizzo Island]] - game description * [[Swirling Blades: Desert Thunder]] - Kazade's choplifter remix ;) * [[Summoning Signals]] - a strange poetic game with radio. == Unknown Status == == Inactive == == Released == baa6cc4d042a70b53959a155de503107330a7ca7 88 61 2020-01-10T00:55:53Z Unknown user 0 /* Active Development */ wikitext text/x-wiki == Active Development == * [[Rizzo Island]] - game description * [[Swirling Blades: Desert Thunder]] - Kazade's choplifter remix ;) * [[Summoning Signals]] - a strange poetic game with radio. {| class="wikitable" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |} == Unknown Status == == Inactive == == Released == 5c8c385f529461575263f23005fde033cfa1ad28 89 88 2020-01-10T00:59:32Z Unknown user 0 /* Released */ wikitext text/x-wiki == Active Development == * [[Rizzo Island]] - game description * [[Swirling Blades: Desert Thunder]] - Kazade's choplifter remix ;) * [[Summoning Signals]] - a strange poetic game with radio. {| class="wikitable" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |} == Unknown Status == == Inactive == == Released == {| class="wikitable" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |} 1953ca0170faa687f8ac8afc123efec2a5274e8f Summoning Signals 0 17 63 49 2020-01-10T00:07:32Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Description -- insert game description -- **Type** : Artgame - Puzzle - ??? **Website** : [https://www.patreon.com/12dbsoft](https://www.patreon.com/12dbsoft) [https://magnes.itch.io/summoning-signals](https://magnes.itch.io/summoning-signals) **Release Date** : 2020 ## Technical * 2D high resolution sprites using [[GLdc]] * Main engine in C. Game code is in LUA. bb557d59304e0ca881b25c58035964d27d483241 Dreamcast emulators 0 4 64 38 2020-01-10T00:08:29Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? * Platform : Android, Windows ### Supported feature ### Known issues ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ad278d3c82f746bd70c95d6d402bdccf055c7f2e 108 64 2020-01-10T02:36:49Z Unknown user 0 Darc moved page [[Emulators]] to [[Dreamcast emulators]] wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : SKMP * Status : Active-ish ? * Platform : Android, Windows ### Supported feature ### Known issues ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ad278d3c82f746bd70c95d6d402bdccf055c7f2e Dreamcast.wiki 0 1 65 53 2020-01-10T00:10:07Z Unknown user 0 /* Welcome to dreamcast.wiki */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[Peripherals]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[DreamEye webcam]] ** [[Neo-Geo Pocket Color link cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] c41007d21b300c0b89147fdd5b0985ee603f3985 73 65 2020-01-10T00:23:21Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] * [[Maple bus]] ** [[DreamEye webcam]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] c77134d68fd9d1b4d8c23e41914c0159b1762f99 79 73 2020-01-10T00:35:13Z Unknown user 0 /* Software */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] * [[Maple bus]] ** [[DreamEye webcam]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] 0200f25e875ae392ca5c5f8d4e89a31e64ca373b 83 79 2020-01-10T00:48:58Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] * [[Maple bus]] ** [[DreamEye webcam]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] ece3607d432e322f4719117c19cdd7a1f855e86a 84 83 2020-01-10T00:50:36Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] * [[Maple bus]] ** [[DreamEye webcam]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] 0f1bcba55f5867d9568d77068d69aa1f8133bea1 85 84 2020-01-10T00:52:20Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] * [[Maple bus]] ** [[DreamEye webcam]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] cee246538fa10e1d94fd36e36da34fe48898a4a8 86 85 2020-01-10T00:54:18Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [Zip drive]] * [[Maple bus]] ** [[Light gun]] ** [[Fishing rod]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] e1aab80bbe5e770ee4018bda79d51c13ec96c572 87 86 2020-01-10T00:54:31Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Light gun]] ** [[Fishing rod]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] 112415b845260cc3cbb76a1ddee7704b8c7edda1 90 87 2020-01-10T01:08:37Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]] * [[Optical drive replacements]] * [[DCHDMI]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] bab2ebc7a328761063f73f0a6d25b0cc5d74e2b5 91 90 2020-01-10T01:10:09Z Unknown user 0 /* Hardware */ wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] ed3f81eabc1c5239895c7a1bab4de96285ef5ee0 93 91 2020-01-10T02:07:55Z Unknown user 0 wikitext text/x-wiki __NOTOC__ = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] 160353b57ac1bf3a9b467273cbee021a4637cb87 94 93 2020-01-10T02:08:14Z Unknown user 0 wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ c851aa1e21418221847f0ad2628dd1b10b26626b 95 94 2020-01-10T02:09:30Z Unknown user 0 Darc moved page [[Main Page]] to [[Welcome]] without leaving a redirect wikitext text/x-wiki = Welcome to dreamcast.wiki = A compendium of Dreamcast-related knowledge == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ c851aa1e21418221847f0ad2628dd1b10b26626b 97 95 2020-01-10T02:10:19Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ a1bb8a7e1920061f1d244fb5dc5a578a1b89c952 98 97 2020-01-10T02:10:50Z Unknown user 0 Darc moved page [[Welcome]] to [[Dreamcast.wiki]] without leaving a redirect wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ a1bb8a7e1920061f1d244fb5dc5a578a1b89c952 100 98 2020-01-10T02:11:32Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo-Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 7376e020d14de1109f0ad2d5f9a86bb083cb1120 105 100 2020-01-10T02:31:01Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Emulators]] * [[Indie games]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 796083a3cfb71edaf15f910b1978f17006b98bee Development 0 2 66 54 2020-01-10T00:11:03Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[KallistiOS - KOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * MacOSX === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprite using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR 4ce31b809d143fb7aaccf0ecd8d6cc2c89beaf87 67 66 2020-01-10T00:11:15Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[KallistiOS - KOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Win ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * MacOSX === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR 6c3a2fbec59a236349248c6e79ab5275c5950f61 Dcload-ip 0 23 68 2020-01-10T00:12:27Z Unknown user 0 Created page with "{{DISPLAYTITLE:dcload-ip}} dcload-ip is a homebrew program which allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug co..." wikitext text/x-wiki {{DISPLAYTITLE:dcload-ip}} dcload-ip is a homebrew program which allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. f081db4f2e1895c391822f2d1ab6b5f1b8a70e19 69 68 2020-01-10T00:12:56Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program which allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. {{DISPLAYTITLE:dcload-ip}} fc5b5a477d331956c45a0e08191da0c1db7beb36 GLdc 0 24 70 2020-01-10T00:15:54Z Unknown user 0 Created page with "{{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is a openGL implementation for the Dreamcast that is actively developed by Kazade. ## Building GLdc **!! Make sure you c..." wikitext text/x-wiki {{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is a openGL implementation for the Dreamcast that is actively developed by Kazade. ## Building GLdc **!! Make sure you clone this repo in the `$KOS_BASE/addons` folder !!** `cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git` Once the folder is cloned `cd GLdc && make defaultall && make create_kos_link` You can now link GLdc using `-lGLdc` 880407ad1b2dcd78cee979d44b653fd490dd6b23 71 70 2020-01-10T00:16:18Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is a openGL implementation for the Dreamcast that is actively developed by Kazade. ## Building GLdc ** Make sure you clone this repo in the `$KOS_BASE/addons` folder ** `cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git` Once the folder is cloned `cd GLdc && make defaultall && make create_kos_link` You can now link GLdc using `-lGLdc` 4efb177ddc7f8ef5f9f2add2cb4e31e4d2772136 74 71 2020-01-10T00:25:37Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is an OpenGL implementation for the Dreamcast that is actively developed by Kazade. MrNeo also contributed to the testing and optimisation of GLdc ## Features Supports most of the OpenGL 1.2 implementation. ## Known Issue Lighting performance is still being worked on. ## Projects using GLdc * [[Summoning Signals]] ## Building GLdc ** Make sure you clone this repo in the `$KOS_BASE/addons` folder ** `cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git` Once the folder is cloned `cd GLdc && make defaultall && make create_kos_link` You can now link GLdc using `-lGLdc` 741f7434c169a32acbdb2b9ae9cfdea1d93efb74 75 74 2020-01-10T00:26:04Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is an OpenGL implementation for the Dreamcast that is actively developed by Kazade. MrNeo also contributed to the testing and optimisation of GLdc ## Features Supports most of the OpenGL 1.2 implementation. ## Known Issue Lighting performance is still being worked on. ## Projects built with GLdc * [[Simulant engine]] * [[Summoning Signals]] ## Building GLdc ** Make sure you clone this repo in the `$KOS_BASE/addons` folder ** `cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git` Once the folder is cloned `cd GLdc && make defaultall && make create_kos_link` You can now link GLdc using `-lGLdc` b9afff78dd3e5467822331e08bcb43ba700531dc 76 75 2020-01-10T00:26:17Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is an OpenGL implementation for the Dreamcast that is actively developed by Kazade. MrNeo also contributed to the testing and optimisation of GLdc ## Features Supports most of the OpenGL 1.2 implementation. ## Known Issue Lighting performance is still being worked on. ## Projects built with GLdc * [[Simulant|Simulant engine]] * [[Summoning Signals]] ## Building GLdc ** Make sure you clone this repo in the `$KOS_BASE/addons` folder ** `cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git` Once the folder is cloned `cd GLdc && make defaultall && make create_kos_link` You can now link GLdc using `-lGLdc` d18979c9851e26781ef693111e4e0f0aeb05154b IDE hard drive modification 0 25 72 2020-01-10T00:18:02Z Unknown user 0 Created page with "The Dreamcast IDE hard drive modification allows one to connect an IDE hard drive (or SATA hard drive, with a proper compatible adapter) to the Dreamcast for storage of files..." wikitext text/x-wiki The Dreamcast IDE hard drive modification allows one to connect an IDE hard drive (or SATA hard drive, with a proper compatible adapter) to the Dreamcast for storage of files and games. Using [[DreamShell]], one can execute games from the hard drive with great (although not perfect) compatibility and access times. c422e365c94c5d1923acda7b2e75acbc95c50e1f MediaWiki:Sidebar 8 10 77 32 2020-01-10T00:28:53Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** simulant-discord-url|Simulant Discord ** Software|Software ** Hardware|Hardware ** Development|Development ** Repair|Repair * wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES 654057e1beec0811b5418feb9217e8c8a5f3ca81 MediaWiki:Simulant-discord-url 8 26 78 2020-01-10T00:29:14Z Unknown user 0 Created page with "https://discord.gg/TYsvK9t" wikitext text/x-wiki https://discord.gg/TYsvK9t 450f086c12020f5d3ac1eb4181831dfb5d1748ed Engine & Library 0 27 80 2020-01-10T00:37:30Z Unknown user 0 Created page with "{{MARKDOWN}} This list is a copy from the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamc..." wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [nuQuake](https://gitlab.com/HaydenKow/nuquake) - Quake engine by MrNeo240 * [radQuake]() - Quake engine by Ian Micheal * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 8f68da1932e8897f270903b6db20e6b732ee7bae 81 80 2020-01-10T00:38:03Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the (awesome-dreamcast)[https://github.com/dreamcastdevs/awesome-dreamcast] repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [nuQuake](https://gitlab.com/HaydenKow/nuquake) - Quake engine by MrNeo240 * [radQuake]() - Quake engine by Ian Micheal * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) cf9e69dd573092b1def073bef25d6ba989165921 82 81 2020-01-10T00:38:20Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [nuQuake](https://gitlab.com/HaydenKow/nuquake) - Quake engine by MrNeo240 * [radQuake]() - Quake engine by Ian Micheal * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) eee1f4f9eabe44e1c5cc3f07ba5021fe02b7072d MediaWiki:Mainpage 8 28 96 2020-01-10T02:09:47Z Unknown user 0 Created page with "Welcome" wikitext text/x-wiki Welcome ca4f9dcf204e2037bfe5884867bead98bd9cbaf8 99 96 2020-01-10T02:11:08Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki 743c91077a2ab08ea48689e51799c15b5d2c035c Zip drive 0 29 101 2020-01-10T02:13:53Z Unknown user 0 Created page with "The Dreamcast Zip drive was a planned, unreleased upgrade for the Dreamcast console. It would have connected to the bottom of the Dreamcast using the [[G2 bus]] connector, sim..." wikitext text/x-wiki The Dreamcast Zip drive was a planned, unreleased upgrade for the Dreamcast console. It would have connected to the bottom of the Dreamcast using the [[G2 bus]] connector, similar to the [[Dreamcast Karaoke]] unit. It would have added a Zip disk drive as well as a USB port to the Dreamcast. 873db38e09f44bc0e7ceccbced5cc5e40bbf44f1 MIDI adapter 0 30 102 2020-01-10T02:16:31Z Unknown user 0 Created page with "The MIDI adapter is a Dreamcast peripheral that connects to the serial port and allows MIDI instrument input and output for use with the Japanese-only title O-to-i-re: Dreamca..." wikitext text/x-wiki The MIDI adapter is a Dreamcast peripheral that connects to the serial port and allows MIDI instrument input and output for use with the Japanese-only title O-to-i-re: Dreamcast Sequencer. 31e41b37e2fd566d20505d05b3c8e5f36e6ab8d0 LAN adapter 0 31 103 2020-01-10T02:26:11Z Unknown user 0 Created page with "The Dreamcast LAN adapter (not to be confused with the superior [[Broadband adapter]]) is a Japanese-only peripheral that connects to the [[G2 bus]] and provides the Dreamcast..." wikitext text/x-wiki The Dreamcast LAN adapter (not to be confused with the superior [[Broadband adapter]]) is a Japanese-only peripheral that connects to the [[G2 bus]] and provides the Dreamcast with 10mbps network connectivity via a Fujitsu MB86967 chip. The only official software that works with the LAN adapter is the Dream Passport for LAN web browser. No official games from any region are compatible with the LAN adapter. Homebrew software that is compatible with the Broadband adapter is also compatible with the LAN adapter, however, except that software is uncommonly tested with the adapter due to its rarity. daec56ef71a48f1ef0c2b958cb9d272db2b666ff VS cable 0 32 104 2020-01-10T02:29:17Z Unknown user 0 Created page with "The Dreamcast VS cable is a rare, serial-based cable that connects two Dreamcast consoles together for multiplayer games. The cable was only released in Japan. There was also..." wikitext text/x-wiki The Dreamcast VS cable is a rare, serial-based cable that connects two Dreamcast consoles together for multiplayer games. The cable was only released in Japan. There was also an aftermarket version released by Dragoncast, but this cable is also rare. Only 5 titles are compatible. * Aero Dancing F * Aero Dancing i * Cyber Troopers Virtual-On: Oratorio Tangram * F355 Challenge * Sega Tetris 29d4f04858b53e47bd49d6e26a9ee7ff298b1350 Neo Geo Pocket Color link cable 0 33 106 2020-01-10T02:34:15Z Unknown user 0 Created page with "The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited li..." wikitext text/x-wiki The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported. * Bikkuriman 2000 Viva! Festival! connects to Bikkuriman 2000 Viva! Pocket Festival! * Capcom vs. SNK: Millennium Fight 2000 connects to SNK vs. Capcom: Match of the Millennium * Capcom vs. SNK 2: Millionaire Fighting 2001 connects to SNK vs. Capcom: Card Fighters 2 Expand Edition * Cool Cool Toon connects to Cool Cool Jam * The King of Fighters: Evolution King of Fighters: Battle de Paradise * The King of Fighters Dream Match '99 connects to King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium 4117be5a8cc096cf7ff8be1eedca4e7b684b32bb 107 106 2020-01-10T02:34:24Z Unknown user 0 wikitext text/x-wiki The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported. * Bikkuriman 2000 Viva! Festival! connects to Bikkuriman 2000 Viva! Pocket Festival! * Capcom vs. SNK: Millennium Fight 2000 connects to SNK vs. Capcom: Match of the Millennium * Capcom vs. SNK 2: Millionaire Fighting 2001 connects to SNK vs. Capcom: Card Fighters 2 Expand Edition * Cool Cool Toon connects to Cool Cool Jam * The King of Fighters: Evolution connects to King of Fighters: Battle de Paradise * The King of Fighters Dream Match '99 connects to King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium c20de97c8a8fa70449bfb03df81f4652301da4c9 Emulators 0 34 109 2020-01-10T02:36:49Z Unknown user 0 Darc moved page [[Emulators]] to [[Dreamcast emulators]] wikitext text/x-wiki #REDIRECT [[Dreamcast emulators]] 5480f90768e00d228df5a6d3d03332483bfd5b71 Dreamcast.wiki 0 1 110 105 2020-01-10T02:36:52Z Unknown user 0 /* Software */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] == Hardware == * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} d763b311152bac438048c830aa00483b0ad70730 117 110 2020-01-10T03:13:56Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 4080005df79211e37b3dbad02c41c4ca2ab9f28d 137 117 2020-01-10T03:57:02Z Unknown user 0 /* Software */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} d4d191080b9a0736c6d1d23cd3baa9c642744739 144 137 2020-01-10T04:19:21Z Unknown user 0 /* Technical Pages */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]] ** [[Arcade stick]] ** [[Twin stick]] ** [[Race wheel]] ** [[Light gun]] ** [[Fishing rod]] ** [[Maracas]] ** [[DreamEye webcam]] ** [[Microphone]] ** [[Jump pack]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 0169e167a367276607920e477a372856171bb9ef 152 144 2020-01-10T04:53:52Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]] ** [[Broadband adapter]] ** [[LAN adapter]] ** [[Dreamcast Karaoke]] ** [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]] ** [[VS cable]] ** [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 1d1669c96e87c279d0cb2ba9b69d2d298330b6e6 156 152 2020-01-10T04:54:51Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Dreamcast Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 087e4fc683cabbb3ab95179e9bc7b67eefdd866f 158 156 2020-01-10T04:55:14Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[Optical drive replacements]] * [[Serial SD card adapter]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Dreamcast Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 601b4caa7feb3581eea0ff33610ad8c7eecca29a IP.BIN 0 35 111 2020-01-10T02:57:18Z Unknown user 0 Created page with "== Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an image..." wikitext text/x-wiki == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an image in [[MR]] Format * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Load address !Contents |- |0x0000-00FF |8C008000-8C0080FF |Meta information |- |0x0100-02FF |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required[[IP.BIN#Bootstrap]]) |} == Execution Flow Overview == bleh == Deeper Look into User Code == === Bootstrap === bloh <ref name="Perry">Perry's Handbook, Sixth Edition, McGraw-Hill Co., 1984.</ref> ==References== <references/> 2287879142df5547ebacd3543c70ed8699bffe48 112 111 2020-01-10T02:58:19Z Unknown user 0 wikitext text/x-wiki == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an image in [[MR]] Format * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Load address !Contents |- |0x0000-00FF |8C008000-8C0080FF |Meta information |- |0x0100-02FF |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required[[#Bootstrap]]) |} == Execution Flow Overview == bleh == Deeper Look into User Code == === Bootstrap === bloh <ref name="Perry">Perry's Handbook, Sixth Edition, McGraw-Hill Co., 1984.</ref> ==References== <references/> f43d6a569e51a3cdfdbeb08723b1894c0a34fc0f 121 112 2020-01-10T03:20:59Z Unknown user 0 wikitext text/x-wiki == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an image in [[MR]] Format * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * a custom [[MR]] image can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== Code here ==References== <references/> 52407ab2b1a796c93811bc7e6dcd2a5ff5985dbc 138 121 2020-01-10T04:06:02Z Unknown user 0 wikitext text/x-wiki == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an [[MR Image]] * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * a custom [[MR Image]] can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== This is Generally where all the base setup code is kept so our binary has a known, and clean execution environment in which it starts. In [[Warez]] releases this is the area that is responsible for a very sneaky trick. The [[1ST_READ.BIN]] binary is kept as is on the disc, but then when scramble loaded by the bios (See [[Dreamcast_Boot_Process]] for further)) it will be unusable, so code was written to unscramble, the now ruined binary, in-place. The second part of this trick also reinitializes the [[GD-ROM]] drive and passes the [[HOLLY]] bios check so that the game may access the data on the disc and execute normally. ==== Other uses ==== * [[neoIP]] is a complete open source replacement for these bootstraps and is currently able to load: homebrew, official Katana and WINCE binaries from either a [[GD-ROM]] or [[CD-ROM]] developed by [[HaydenKow]] * [[IP.BIN Replacement]] This as far as I know is the first LEGAL ip.bin replacement for the dc, however it is pretty much untested. Developed by LiENUS ==References== <references/> e67e1b8d5b28fb2401ec2c79b2e202cd5bb82fc1 KallistiOS 0 21 113 59 2020-01-10T03:07:36Z Unknown user 0 Darc moved page [[KallistiOS - KOS]] to [[KallistiOS]] wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Dan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of libdream, the first free developer library for Dreamcast. Libdream was also written by Dan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] d40783b53e1b38203682b5b6ee20f1904dd7b868 Development 0 2 115 67 2020-01-10T03:08:27Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR 2924942625f80c47eb623543459561ada9539de8 116 115 2020-01-10T03:13:47Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR e9df35142aa4e2b1c640a982de9ef89ad0bc559e 130 116 2020-01-10T03:43:08Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file === Optimization === * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] aa6f474c2b482c683a9aa4c6b3d6bf8497e7b294 Using dcload-ip with Linux 0 37 118 2020-01-10T03:14:11Z Unknown user 0 Created page with "{{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no rout..." wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in between. ### Dreamcast side Get a selfbooting version of [dc-load-ip](http://download.sizious.com/dc/dctool/dcload-ip-1.0.4.7z). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code I'm currently using a [pre-compiled dcload-ip](http://napalm-x.thegypsy.com/adk/dc/dcload-ip/index.html) which seems to work fine. You can now use that program to send your file to the DC. Make sure you dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ bbae78d19ca09b9196fafa63c25c385e52c5f5dc 122 118 2020-01-10T03:33:51Z Unknown user 0 Darc moved page [[Linux : BBA with dcload-ip]] to [[Using dcload-ip with Linux]] wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in between. ### Dreamcast side Get a selfbooting version of [dc-load-ip](http://download.sizious.com/dc/dctool/dcload-ip-1.0.4.7z). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code I'm currently using a [pre-compiled dcload-ip](http://napalm-x.thegypsy.com/adk/dc/dcload-ip/index.html) which seems to work fine. You can now use that program to send your file to the DC. Make sure you dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ bbae78d19ca09b9196fafa63c25c385e52c5f5dc 133 122 2020-01-10T03:51:41Z Unknown user 0 We have dcload-ip with DHCP and bugfixes now, use that instead of 1.0.4 wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install. My dreamcast is connected directly to my computer, no router in between. ### Dreamcast side Get a selfbooting version of [dc-load-ip (in the "Releases" section)](https://github.com/Moopthehedgehog/dcload-ip). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code I'm currently using a [pre-compiled dcload-ip](http://napalm-x.thegypsy.com/adk/dc/dcload-ip/index.html) which seems to work fine. You can now use that program to send your file to the DC. Make sure you dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ c913784f5e7ff0d07b7e6b4c899486831569983a 134 133 2020-01-10T03:54:14Z Unknown user 0 Um, we really should fix this for the latest dcload-ip version wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install. My Dreamcast is connected directly to my computer, no router in between, using dcload-ip with a hardcoded static IP address. ### Dreamcast side Get a selfbooting version of [dc-load-ip (in the "Releases" section)](https://github.com/Moopthehedgehog/dcload-ip). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side (not necessary if using pre-built DHCP version) We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code You can now use that program to send your file to the DC. Make sure your dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ 4858d12b6f571928b9d4cefe6eeb4439200790f1 135 134 2020-01-10T03:54:48Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, no router in between, using dcload-ip with a hardcoded static IP address. ### Dreamcast side Get a selfbooting version of [dc-load-ip (in the "Releases" section)](https://github.com/Moopthehedgehog/dcload-ip). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side (not necessary if using pre-built DHCP version) We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code You can now use that program to send your file to the DC. Make sure your dreamcast is running **dc-load-ip**. I've renamed the program to dc-tool-ip for simpler access. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ 0f1d606503513120d9069c802b7374f9c6e9582f 136 135 2020-01-10T03:56:17Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Linux : using dcload-ip with the BBA This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, no router in between, using dcload-ip with a hardcoded static IP address. ### Dreamcast side Get a selfbooting version of [dc-load-ip (in the "Releases" section)](https://github.com/Moopthehedgehog/dcload-ip). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ### Computer side (not necessary if using pre-built DHCP version) We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: ` sudo arp -s [local IP address] [MAC address]` `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running **dc-load-ip**. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ### Notes (for non-DHCP use) #### arp The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my `environ.sh` script. #### Adding a host name Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ 6c505e37ea1ff799ddb51667230ee18de29cb1ad Broadband adapter 0 5 119 16 2020-01-10T03:14:33Z Unknown user 0 Blanked the page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 125 119 2020-01-10T03:38:09Z Unknown user 0 wikitext text/x-wiki The Dreamcast Broadband adapter ("'''BBA'''") is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. 40eb91e805c51275f794e6df393de1caa1fc0cf8 129 125 2020-01-10T03:42:47Z Unknown user 0 wikitext text/x-wiki The Dreamcast Broadband adapter ("'''BBA'''") is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a somewhat rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. A program loader called DCLOAD-IP<ref>https://github.com/sizious/dcload-ip</ref> is also designed for use with it to aid in Dreamcast development. 3309972431866990a67a27a05b68e1b7888fd069 Hardware overview 0 38 120 2020-01-10T03:18:16Z Unknown user 0 Created page with "*'''CPU''': Hitachi SuperH SH-4 RISC CPU @ 200MHz *'''GPU''': NEC PowerVR2 with 8MB of texture memory *'''Sound''': Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memo..." wikitext text/x-wiki *'''CPU''': Hitachi SuperH SH-4 RISC CPU @ 200MHz *'''GPU''': NEC PowerVR2 with 8MB of texture memory *'''Sound''': Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memory''': 16MB system memory *'''Storage''': [[GD-ROM drive]] *'''Network''': 33.6K or 56K modem 3beb8eb0ddc159111c2210a9b42f86f2947c23b5 Linux : BBA with dcload-ip 0 39 123 2020-01-10T03:33:51Z Unknown user 0 Darc moved page [[Linux : BBA with dcload-ip]] to [[Using dcload-ip with Linux]] wikitext text/x-wiki #REDIRECT [[Using dcload-ip with Linux]] eb457022f3b636b9f7aee21e44c8b18cc1a58bbf Dreamcast emulators 0 4 124 108 2020-01-10T03:35:49Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : skmp, others. Derived from nullDC. * Status : Active, Under rewrite * Platform : Android, Windows, Linux, OSX, html5 ### Supported feature ### Known issues - Extremely buggy ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp, ZeZu, PsyMan * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ## Demul * Official page : [http://demul.emulation64.com/](http://demul.emulation64.com/) * Developed by : ?? * Status : Inactive * Platform : Windows ### Supported feature - MMU, Naomi 2 ### Known issues 0e67f38fe5bfbf4eba1317d5e8adb2158ce3bbc9 131 124 2020-01-10T03:46:00Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : skmp, others. Derived from nullDC. * Status : Active, Under rewrite * Platform : Android, Windows, Linux, OSX, html5 ### Supported feature ### Known issues - Extremely buggy ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues - No sound support for homebrew with HLE bios ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp, ZeZu, PsyMan * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ## Demul * Official page : [http://demul.emulation64.com/](http://demul.emulation64.com/) * Developed by : ?? * Status : Inactive * Platform : Windows ### Supported feature - MMU, Naomi 2 ### Known issues 782af4b672d3ef944111cdda763d7e3255c8ed4e User:Magnes 2 40 126 2020-01-10T03:39:24Z Unknown user 0 Created page with "{{MARKDOWN}} I'm the lead programmer at [12db.soft](https://www.patreon.com/12dbsoft). ## Projects * [[Summoning Signals]] * [[Reaperi Cycle]] * [VMU_SQUAD](https://robyprov..." wikitext text/x-wiki {{MARKDOWN}} I'm the lead programmer at [12db.soft](https://www.patreon.com/12dbsoft). ## Projects * [[Summoning Signals]] * [[Reaperi Cycle]] * [VMU_SQUAD](https://robyprovost.com/VMU_SQUAD), [Article on DC Junkyard](http://www.thedreamcastjunkyard.co.uk/2016/11/digital-artists-create-jet-set-radio.html) 3938bed262ced3e841336ec051575a53d138b9b2 127 126 2020-01-10T03:39:44Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Lead programmer at [12db.soft](https://www.patreon.com/12dbsoft). ## Projects * [[Summoning Signals]] * [[Reaperi Cycle]] * [VMU_SQUAD](https://robyprovost.com/VMU_SQUAD), [Article on DC Junkyard](http://www.thedreamcastjunkyard.co.uk/2016/11/digital-artists-create-jet-set-radio.html) 4e65b21e8f7a9ad4dd2888de04593e1d649a1f83 128 127 2020-01-10T03:41:02Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Lead programmer at [12db.soft](https://www.patreon.com/12dbsoft). Most of my project are made using a vary lightweight C engine using [[GLdc]] with all the game logic being written in LUA (using libLua in kos-port). ## Projects * [[Summoning Signals]] * [[Reaperi Cycle]] * [VMU_SQUAD](https://robyprovost.com/VMU_SQUAD), [Article on DC Junkyard](http://www.thedreamcastjunkyard.co.uk/2016/11/digital-artists-create-jet-set-radio.html) 7b0591fd2c7474a8f26dcfa611b2aa51bf4bf3e4 Objdump 0 41 132 2020-01-10T03:47:45Z Unknown user 0 Created page with "== Random Snippets == * using Objdump to disassemble part of a file, showing how to change the start and stop offsets and also changing from what address we are basing this on..." wikitext text/x-wiki == Random Snippets == * using Objdump to disassemble part of a file, showing how to change the start and stop offsets and also changing from what address we are basing this on <code>sh-elf-objdump -D -b binary -m sh4 -EL --adjust-vma=0x8c008000 --start-address=0x8c00b800 --stop-address=0x8c00b830 IP.BIN</code> 15a65d4bf7b2be45ffafd5fdd50192ce054e86d4 Template:Release 10 42 139 2020-01-10T04:11:42Z Unknown user 0 Created page with "<includeonly>{| cellpadding="0" cellspacing="0" class="infobox" style="margin-left:1em" width="{{ #if: {{{boxwidth|}}} | {{{boxwidth}}} | 262 }}px" | style="text-align: cente..." wikitext text/x-wiki <includeonly>{| cellpadding="0" cellspacing="0" class="infobox" style="margin-left:1em" width="{{ #if: {{{boxwidth|}}} | {{{boxwidth}}} | 262 }}px" | style="text-align: center;" | {{#if: {{{noscreen|}}} | | {{imageexists | file = {{#if: {{{titlescreen|}}} | {{{titlescreen}}} | {{PAGENAME}}-title.png }} | maxwidth = 320 | caption= Title Screen | property= Has title screenshot | missingcat = Missing title screenshots }}}} |-class="infobox-title" ! {{#replace:{{PAGENAME}}|!|&#33;}} |- |style="padding: 10px; line-height: 1.5em;" | {| {{ #if: {{{date|}}} | {{!}}'''Date''' {{!}}{{!}} {{{date}}} {{!}}- | }} {{ #if: {{{version|}}} | {{!}}'''Version''' {{!}}{{!}} {{{version}}} {{!}}- | }} {{ #if: {{{builddate|}}} | {{!}}'''Build date''' {{!}}{{!}} [[Has build date::{{{builddate}}}]] [[Has sort date::{{{builddate}}}| ]] {{!}}- | [[Has sort date::1970| ]] }} {{ #if: {{{buildname|}}} | {{!}}'''Build name''' {{!}}{{!}} [[Has build name::{{{buildname}}}]] {{!}}- | }} {{ #if: {{{status|}}} | {{!}}'''Dump status''' {{!}}{{!}} [[Has status::{{{status}}}]] {{!}}- | }} {{ #if: {{{releasedby|}}} | {{!}}'''Released by''' {{!}}{{!}} {{Autolink user|{{{releasedby}}} }} [[Was released by::{{{releasedby}}}| ]] {{!}}- | }} {{ #if: {{{filereleasedate|}}} | {{!}}'''File release date''' {{!}}{{!}} [[Has file release date::{{{filereleasedate}}}]] [[Has sort date::{{{filereleasedate}}}| ]] {{!}}- | [[Has sort date::1970| ]] }} {{ #if: {{{origin_type|}}} | {{!}} style="padding-top: 14px" {{!}}'''Origin''' {{!}} style="padding-top: 14px" {{!}} {{{origin_type}}} {{!}}- | }} {{ #if: {{{origin_file|}}} | {{!}}'''File''' {{!}}{{!}} <small>{{{origin_file}}}</small> {{!}}- | }} {{ #if: {{{origin_files|}}} | {{!}}'''Files''' {{!}}{{!}} <small>{{{origin_files}}}</small> }} [[Has origin files::{{{origin_files}}}|]] {{!}}- | }} {{ #if: {{{game|}}} | {{!}} style="padding-top: 14px" {{!}}'''Game''' {{!}} style="padding-top: 14px" {{!}} [[Has game::{{{game}}}]] [[Category:{{{game}}} prototypes]] {{!}}- | }} {{ #if: {{{name|}}} | {{!}} style="padding-top: 14px" {{!}}'''Name''' {{!}} style="padding-top: 14px" {{!}} {{{name}}} {{!}}- | }} {{ #if: {{{system|}}} | {{!}}'''System''' {{!}}{{!}} {{ #if: {{{game|}}} | {{system|{{{system}}}}} | {{{system}}} }} [[Has system::{{{system}}}| ]] {{!}}- | }} {{ #if: {{{genre|}}} | {{!}}'''Genre''' {{!}}{{!}} [[Has genre::{{{genre}}}]] {{!}}- | }} {{ #if: {{{final_builddate|}}} | {{!}}'''Final build''' {{!}}{{!}} [[Has final build date::{{{final_builddate}}}]] {{!}}- | }} {{ #if: {{{release_date|}}} | {{!}}'''Release&nbsp;date''' {{!}}{{!}} [[Has final release date::{{{release_date}}}]] {{!}}- | }} {{ #switch: {{{unreleased|}}} | yes | Yes = {{!}}'''Release&nbsp;date''' {{!}}{{!}} Unreleased [[Category:Unreleased game prototypes]] [[Is unreleased::true| ]] {{!}}- | [[Is unreleased::false| ]] }} |} |}{{#default_form:Release}}</includeonly> 125ca37a6a4481d70dc28c09f6ea107b86ce796e Template:Imageexists 10 43 140 2020-01-10T04:13:38Z Unknown user 0 Created page with "<includeonly>{{#ifexist: File:{{{file}}} |{{#if: {{{property|}}} | [[{{{property|}}}::File:{{{file}}}|]] |}}File:{{{file}}}{{ #if: {{{maxwidth|}}} | {{#ifexpr: {{#mediawidt..." wikitext text/x-wiki <includeonly>{{#ifexist: File:{{{file}}} |{{#if: {{{property|}}} | [[{{{property|}}}::File:{{{file}}}|]] |}}[[File:{{{file}}}{{ #if: {{{maxwidth|}}} | {{#ifexpr: {{#mediawidth:File:{{{file}}}}}>={{{maxwidth}}} | {{!}}{{{maxwidth}}}px |}}|}}{{ #if: {{{link|}}} | {{!}}link={{{link}}} |}}{{ #if: {{{caption|}}} | {{!}}{{{caption}}} | }}]] | [[File:NoImage.png|link={{fullurl:Special:Upload|wpDestFile={{{file}}}}}|Click to upload a new image...]] {{#if: {{{missingcat|}}} | [[Category:{{{missingcat}}}|{{PAGENAME}}]] | }}<span style="display: none;">[[Media:{{{file}}}|Dummy link]]</span>}}</includeonly><noinclude> Lovingly lifted from TCRF, somewhat edited.</noinclude> 31f06aad2a4d855afd6cb0b618a4d5968a461f7c Template:Download 10 44 141 2020-01-10T04:14:37Z Unknown user 0 Created page with "{|cellpadding="0" cellspacing="0" class="infobox download" style="float:none; {{#if: {{{file|}}} ||display: none}}" | |- |style="padding: 10px 15px; line-height: 2em;" | Med..." wikitext text/x-wiki {|cellpadding="0" cellspacing="0" class="infobox download" style="float:none; {{#if: {{{file|}}} ||display: none}}" | |- |style="padding: 10px 15px; line-height: 2em;" | [[Media:{{{file}}}|<i class="fa fa-download fa-2x" style="padding-right: 5px"></i> Download {{#if: {{{title|}}} | {{{title}}} | {{PAGENAME}} }} ]] <span style="font-size: 10px">([[:File:{{{file}}}|info]]{{#if: {{{raw|}}} | , [[Media:{{{raw}}}|raw dump]] |}})</span> |} aca74c4d979ef5691861383dbd8117217c9d1cfa Template:Navbox prototype 10 45 142 2020-01-10T04:15:22Z Unknown user 0 Created page with "<includeonly>{{#vardefine:prototype_count|{{#ask:[[Has game::{{{1}}}]]|format=count}}}} {{#ifexpr: {{#var:prototype_count}} > 1 | {{#vardefine:prototypes|{{#ask: Has game::..." wikitext text/x-wiki <includeonly>{{#vardefine:prototype_count|{{#ask:[[Has game::{{{1}}}]]|format=count}}}} {{#ifexpr: {{#var:prototype_count}} > 1 | {{#vardefine:prototypes|{{#ask: [[Has game::{{{1}}}]] |sort=Has sort date |format=ul |limit=120 }}}} {{#arraydefine: systems | {{#ask:[[Has game::{{{1}}}]] [[Has system::+]] |mainlabel=- |headers=hide |?Has system |limit=120 }} | , | sort=asc, unique }} {{Panel| {{{1}}} prototypes | <table> {{#arrayprint:systems||@@@@|<tr>{{#ifexpr: {{#arraysize:systems}} > 1 | <td class="panel-group">@@@@</td>|}}<td> {{#regex: {{#ask: [[Has game::{{{1}}}]] [[Has system::@@@@]] |sort=Has sort date |format=ul |limit=120 }} | /\[\[(.*?\))(.*?)\((.*?)( [pP]rototype(.*?))?\)\]\]/ | [[$1|$3$5]] }} </td></tr>}} </table> |class=navbox}} | }}</includeonly> c6176f43dae196065573eab755462675e7b3e038 Template:Panel 10 46 143 2020-01-10T04:16:16Z Unknown user 0 Created page with "<div class="panel {{{class|}}}"> <div class="panel-heading">{{{1}}}</div> <div class="panel-body">{{{2}}}</div> </div> <div style="clear: left"></div>" wikitext text/x-wiki <div class="panel {{{class|}}}"> <div class="panel-heading">{{{1}}}</div> <div class="panel-body">{{{2}}}</div> </div> <div style="clear: left"></div> 180f7ebf087f9aa57e8ab220e6f314457da322a6 File:0gdtex tut 1.jpg 6 47 145 2020-01-10T04:49:54Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 2.png 6 48 146 2020-01-10T04:51:36Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 3.png 6 49 147 2020-01-10T04:52:02Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 4.png 6 50 148 2020-01-10T04:52:50Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 5.png 6 51 149 2020-01-10T04:53:10Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 6.png 6 52 150 2020-01-10T04:53:25Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 7.png 6 53 151 2020-01-10T04:53:47Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 8.png 6 54 153 2020-01-10T04:54:11Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 9.png 6 55 154 2020-01-10T04:54:28Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 10.png 6 56 155 2020-01-10T04:54:45Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 11.png 6 57 157 2020-01-10T04:55:00Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 12.png 6 58 159 2020-01-10T04:55:15Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:0gdtex tut 13.png 6 59 160 2020-01-10T04:55:32Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Dreamcast.wiki 0 1 161 158 2020-01-10T04:56:25Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Dreamcast Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 0b6426b590670120047841dcfc0ba2b06a1f31b0 163 161 2020-01-10T04:57:16Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Dreamcast Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 8bc61f59ec9c6af4c5344b0e9785c56ad747d4ab 165 163 2020-01-10T04:59:36Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[DCHDMI]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 6d91e227a5f7a52cf84b1f55cdbd812ad3097431 170 165 2020-01-10T05:11:35Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]], [[S/PDIF]], [[DCHDMI]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 026c277f05bc7ddb0fa3c0eda36874041f5b81a1 172 170 2020-01-10T05:22:32Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} f1cf6350819e08e7eb221d682d3a2d248293cdd7 173 172 2020-01-10T05:22:51Z Unknown user 0 /* Modifications */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * [[Dumping GD-ROMs]] * [[Creating bootable homebrew disc]] * Play [[Imports]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 4903918235d2900a31314c2c2e7b25cd88566936 177 173 2020-01-10T05:41:35Z Unknown user 0 /* How To */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 83724aea9a9630b33af86d191058085d46488bec 179 177 2020-01-10T05:43:05Z Unknown user 0 /* Technical Pages */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Dreamcast Boot Process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} f5944cfb4e9c0f821314c5bb998b293918fd7de8 182 179 2020-01-10T05:43:33Z Unknown user 0 /* Technical Pages */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Dreamcast case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 97489e3e21271982aab0c8ef7296ef148585b9dc 183 182 2020-01-10T05:55:36Z Unknown user 0 /* Repair */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 96ae6de7130ce624d9360e620640fc6bbf1e007f 184 183 2020-01-10T05:56:25Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Console variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 1efa5743421f87bb9055c582541087d4b269ff4a 185 184 2020-01-10T05:58:36Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} f8fd961eb835fc952e923b15cc7a5ec4bb639da6 187 185 2020-01-10T06:32:02Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * [[Controller port repair]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} b14bd697ab1960ed0c26cc959ade75780ff3e5a2 188 187 2020-01-10T06:39:12Z Unknown user 0 /* Repair */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} bbf880a336daced1e85b0d87c71dbdc5ed3a78fe 189 188 2020-01-10T06:43:18Z Unknown user 0 /* Modifications */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]] * [[BIOS modification]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} f90cd86a74e36826e585d052a43461c6dfd25957 190 189 2020-01-10T06:43:38Z Unknown user 0 /* Modifications */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 355fdf3900e4a94355997ed354fb3dd552e06472 191 190 2020-01-10T06:52:06Z Unknown user 0 /* Modifications */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[Video mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 60e330e52488a8e82d1b09893823aca49146ce09 192 191 2020-01-10T06:52:36Z Unknown user 0 /* Modifications */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} bba4f9a33f421bf4c1df6a50eaf9c5d996e51d5e GD-ROM 0 7 162 22 2020-01-10T04:57:06Z Unknown user 0 wikitext text/x-wiki The GD-ROM format is Sega's proprietary disc format used for the Sega Dreamcast home console, as well as for the arcade systems [[NAOMI]], [[NAOMI 2]], Triforce, and Chihiro. Holds a [[0GDTEX.PVR]] image that can be shown on the Bios CD player screen. 2668763ac0e676086ac24c44a7eeaa280b2687b5 0GDTEX.PVR 0 60 164 2020-01-10T04:57:29Z Unknown user 0 Created page with "== Info == == Creation Tutorial == Author: [[HaydenKow]] Source: [https://www.reddit.com/r/dreamcast/comments/aa3uq1/question_adding_artwork_to_a_gdi_image/ecpmp52/ Reddit Po..." wikitext text/x-wiki == Info == == Creation Tutorial == Author: [[HaydenKow]] Source: [https://www.reddit.com/r/dreamcast/comments/aa3uq1/question_adding_artwork_to_a_gdi_image/ecpmp52/ Reddit Post] * Video Overview from Super Retrocade ** watch this for an overview and the basic how to for the whole thing *** [https://www.youtube.com/watch?v=GxXO2OtHv9o How to add album art to GDEMU (YouTube)] *** It will absolutely work, and is a solid good with easy to find tools. # Making a better quality PVR Image using photoshop ** Note: using the way discussed in the video will give decent to find results but this gives you better control # Find and image and get it in photoshop : [https://i.imgur.com/hV8pnGC.jpg] # Resize to 256x256 : [https://i.imgur.com/mPjknXv.png] # Split channels: [https://i.imgur.com/NPrHncD.png what you should get [https://i.imgur.com/x9ZMnu4.png] # Press Alt + Shift + Ctrl + S or Save for Web (Legacy): [https://i.imgur.com/nCHGsxh.png] ** For each channel, but should do it for all just doing it once. Merge Back : https://i.imgur.com/eONt6Rq.png Change to RGB, 3 Channel : https://i.imgur.com/SMerMQr.png Make sure this looks correct and not stupid: https://i.imgur.com/33Y41kp.png Back in business! : https://i.imgur.com/igEDUVn.png Save as BMP : https://i.imgur.com/83XHN7K.png Normal, dont go crazy : https://i.imgur.com/1MGbZI2.png Now you have all this : https://i.imgur.com/9wx8rvM.png Run create_pvr.exe or type the command yourself from command.txt, its all the same. Before you do. Check to see if the alpha.bmp lines up well with your created image, the outside should be perfect AS-IS but the inner circle may change depending on your source image, or if you even want your image to hole or not. rename disc.pvr to 0GDTEX.PVR Then use that file from the video above. good luck Result: https://i.imgur.com/D0ukg7L.png I love y'all but setting up my capture setup just isnt worth it for a single screen cap. It will work just as well in the menu though, i promise. edit: forgot to post the file with the tool and BMPs https://www.mediafire.com/file/lmwoe1h362e6p52/Image_-_Copy.rar/file bebabe912c0ca028f2c99f836eeb1572f5ced968 171 164 2020-01-10T05:19:53Z Unknown user 0 /* Creation Tutorial */ wikitext text/x-wiki == Info == == Creation Tutorial == Author: [[HaydenKow]] Source: [https://www.reddit.com/r/dreamcast/comments/aa3uq1/question_adding_artwork_to_a_gdi_image/ecpmp52/ Reddit Post] Files: [[:File:0GDTEX Creation Tool.7z|0GDTEX Creation Tool.7z]] '''Video Overview from Super Retrocade''' * watch this for an overview and the basic how to for the whole thing ::- [https://www.youtube.com/watch?v=GxXO2OtHv9o How to add album art to GDEMU (YouTube)] ::- It will absolutely work, and is a solid good with easy to find tools. <br> '''Making a better quality PVR Image using photoshop''' ::- Note: using the way discussed in the video above will give decent to find results but this gives you better control # Find an image and get it in photoshop : [[File:0gdtex_tut_1.jpg|frameless|border]] # Resize to 256x256 : [[File:0gdtex_tut_2.png|frameless|border]] # Split channels: [[File:0gdtex_tut_3.png|frameless|border]] what you should get [[File:0gdtex_tut_4.png|frameless|border]] # Press Alt + Shift + Ctrl + S or Save for Web (Legacy): [[File:0gdtex_tut_5.png|frameless|border]] #* For each channel, but should do it for all just doing it once. # Merge Back : [[File:0gdtex_tut_6.png|frameless|border]] # Change to RGB, 3 Channel : [[File:0gdtex_tut_7.png|frameless|border]] # Make sure this looks correct and not stupid: [[File:0gdtex_tut_8.png|frameless|border]] # Back in business! : [[File:0gdtex_tut_9.png|frameless|border]] # Save as BMP : [[File:0gdtex_tut_10.png|frameless|border]] # Normal, dont go crazy : [[File:0gdtex_tut_11.png|frameless|border]] # Now you have all this : [[File:0gdtex_tut_12.png|frameless|border]] # Run create_pvr.exe or type the command yourself from command.txt, its all the same. #Before you do. Check to see if the alpha.bmp lines up well with your created image, the outside should be perfect AS-IS but the inner circle may change depending on your source image, or if you even want your image to hole or not. #rename disc.pvr to 0GDTEX.PVR #Then use that file from the video above. good luck #Result: [[File:0gdtex_tut_13.png|frameless|border]] <br> ---- Image Gallery: (idk what im doing) <br> <gallery mode="packed-hover"> Image:0gdtex_tut_1.jpg|''[[commons:Astronotus ocellatus|Astronotus ocellatus]]'' (Oscar) Image:0gdtex_tut_2.png|''[[commons:Salmo salar|Salmo salar]]'' (Salmon Larva) Image:0gdtex_tut_3.png|''[[commons:Epinephelus lanceolatus|Epinephelus lanceolatus]]'' (Giant grouper) Image:0gdtex_tut_4.png|''[[commons:Pterois volitans|Pterois volitans]]'' (Red Lionfish) Image:0gdtex_tut_5.png|''[[commons:Macropodus opercularis|Macropodus opercularis]]'' (Paradise fish) Image:0gdtex_tut_6.png|''[[commons:Canthigaster valentini|Canthigaster valentini]]'' (Valentinni's sharpnose puffer) Image:0gdtex_tut_7.png|[[Image:POTY ribbon 2007.svg|25px]] ''[[commons:Dactylopterus volitans|Dactylopterus volitans]]'' (Flying gurnard) Image:0gdtex_tut_8.png|''[[commons:Semicossyphus pulcher|Semicossyphus pulcher]]'' (California Sheephead) Image:0gdtex_tut_9.png|''[[commons:Category:Pseudorasbora parva|Pseudorasbora parva]]'' (Topmouth gudgeon) Image:0gdtex_tut_10.png|''[[commons:Category:Pterois antennata|Pterois antennata]]'' (Antennata Lionfish) Image:0gdtex_tut_11.png|''[[commons:Novaculichthys taeniourus|Novaculichthys taeniourus]]'' Image:0gdtex_tut_12.png|''[[commons:Synchiropus splendidus|Synchiropus splendidus]]'' (Mandarin fish) Image:0gdtex_tut_13.png|''[[commons:Psetta maxima|Psetta maxima]]'' (Turbot) </gallery> 76da6f65672a3eab7223fe5916d98ea0a60a0f9d 174 171 2020-01-10T05:27:00Z Unknown user 0 wikitext text/x-wiki == Info == == Creation Tutorial == Author: [[HaydenKow]] Source: [https://www.reddit.com/r/dreamcast/comments/aa3uq1/question_adding_artwork_to_a_gdi_image/ecpmp52/ Reddit Post] Files: [[:File:0GDTEX Creation Tool.7z|0GDTEX Creation Tool.7z]] '''Video Overview from Super Retrocade''' * watch this for an overview and the basic how to for the whole thing ::- [https://www.youtube.com/watch?v=GxXO2OtHv9o How to add album art to GDEMU (YouTube)] ::- It will absolutely work, and is a solid good with easy to find tools. <br> '''Making a better quality PVR Image using photoshop''' ::- Note: using the way discussed in the video above will give decent to find results but this gives you better control # Find an image and get it in photoshop : [[File:0gdtex_tut_1.jpg|frameless|border]] # Resize to 256x256 : [[File:0gdtex_tut_2.png|frameless|border]] # Split channels: [[File:0gdtex_tut_3.png|frameless|border]] what you should get [[File:0gdtex_tut_4.png|frameless|border]] # Press Alt + Shift + Ctrl + S or Save for Web (Legacy): [[File:0gdtex_tut_5.png|frameless|border]] #* For each channel, but should do it for all just doing it once. # Merge Back : [[File:0gdtex_tut_6.png|frameless|border]] # Change to RGB, 3 Channel : [[File:0gdtex_tut_7.png|frameless|border]] # Make sure this looks correct and not stupid: [[File:0gdtex_tut_8.png|frameless|border]] # Back in business! : [[File:0gdtex_tut_9.png|frameless|border]] # Save as BMP : [[File:0gdtex_tut_10.png|frameless|border]] # Normal, dont go crazy : [[File:0gdtex_tut_11.png|frameless|border]] # Now you have all this : [[File:0gdtex_tut_12.png|frameless|border]] # Run create_pvr.exe or type the command yourself from command.txt, its all the same. #Before you do. Check to see if the alpha.bmp lines up well with your created image, the outside should be perfect AS-IS but the inner circle may change depending on your source image, or if you even want your image to hole or not. #rename disc.pvr to 0GDTEX.PVR #Then use that file from the video above. good luck #Result: [[File:0gdtex_tut_13.png|frameless|border]] <br> ---- Image Gallery: (idk what im doing) <br> <gallery mode="packed-hover"> Image:0gdtex_tut_1.jpg|''[[commons:Astronotus ocellatus|Astronotus ocellatus]]'' (Oscar) Image:0gdtex_tut_2.png|''[[commons:Salmo salar|Salmo salar]]'' (Salmon Larva) Image:0gdtex_tut_3.png|''[[commons:Epinephelus lanceolatus|Epinephelus lanceolatus]]'' (Giant grouper) Image:0gdtex_tut_4.png|''[[commons:Pterois volitans|Pterois volitans]]'' (Red Lionfish) Image:0gdtex_tut_5.png|''[[commons:Macropodus opercularis|Macropodus opercularis]]'' (Paradise fish) Image:0gdtex_tut_6.png|''[[commons:Canthigaster valentini|Canthigaster valentini]]'' (Valentinni's sharpnose puffer) Image:0gdtex_tut_7.png|''[[commons:Dactylopterus volitans|Dactylopterus volitans]]'' (Flying gurnard) Image:0gdtex_tut_8.png|''[[commons:Semicossyphus pulcher|Semicossyphus pulcher]]'' (California Sheephead) Image:0gdtex_tut_9.png|''[[commons:Category:Pseudorasbora parva|Pseudorasbora parva]]'' (Topmouth gudgeon) Image:0gdtex_tut_10.png|''[[commons:Category:Pterois antennata|Pterois antennata]]'' (Antennata Lionfish) Image:0gdtex_tut_11.png|''[[commons:Novaculichthys taeniourus|Novaculichthys taeniourus]]'' Image:0gdtex_tut_12.png|''[[commons:Synchiropus splendidus|Synchiropus splendidus]]'' (Mandarin fish) Image:0gdtex_tut_13.png|''[[commons:Psetta maxima|Psetta maxima]]'' (Turbot) </gallery> 2fe99b99fa518ae23a5aefd796dfb099d4a19e81 178 174 2020-01-10T05:42:06Z Unknown user 0 wikitext text/x-wiki == Info == == Creation Tutorial == Author: [[HaydenKow]] Source: [https://www.reddit.com/r/dreamcast/comments/aa3uq1/question_adding_artwork_to_a_gdi_image/ecpmp52/ Reddit Post] Files: [[:File:0GDTEX Creation Tool.7z|0GDTEX Creation Tool.7z]] |border|50px '''Video Overview from Super Retrocade''' * watch this for an overview and the basic how to for the whole thing ::- [https://www.youtube.com/watch?v=GxXO2OtHv9o How to add album art to GDEMU (YouTube)] ::- It will absolutely work, and is a solid good with easy to find tools. <br> '''Making a better quality PVR Image using photoshop''' ::- Note: using the way discussed in the video above will give decent to find results but this gives you better control # Find an image and get it in photoshop : [[File:0gdtex_tut_1.jpg|frameless|border]] # Resize to 256x256 : [[File:0gdtex_tut_2.png|frameless|border]] # Split channels: [[File:0gdtex_tut_3.png|frameless|border]] what you should get [[File:0gdtex_tut_4.png|frameless|border]] # Press Alt + Shift + Ctrl + S or Save for Web (Legacy): [[File:0gdtex_tut_5.png|frameless|border]] #* For each channel, but should do it for all just doing it once. # Merge Back : [[File:0gdtex_tut_6.png|frameless|border]] # Change to RGB, 3 Channel : [[File:0gdtex_tut_7.png|frameless|border]] # Make sure this looks correct and not stupid: [[File:0gdtex_tut_8.png|frameless|border]] # Back in business! : [[File:0gdtex_tut_9.png|frameless|border]] # Save as BMP : [[File:0gdtex_tut_10.png|frameless|border]] # Normal, dont go crazy : [[File:0gdtex_tut_11.png|frameless|border]] # Now you have all this : [[File:0gdtex_tut_12.png|frameless|border]] # Run create_pvr.exe or type the command yourself from command.txt, its all the same. #Before you do. Check to see if the alpha.bmp lines up well with your created image, the outside should be perfect AS-IS but the inner circle may change depending on your source image, or if you even want your image to hole or not. #rename disc.pvr to 0GDTEX.PVR #Then use that file from the video above. good luck #Result: [[File:0gdtex_tut_13.png|frameless|border]] <br> ---- Image Gallery: (idk what im doing) <br> <gallery mode="packed-hover"> Image:0gdtex_tut_1.jpg|''[[commons:Astronotus ocellatus|Astronotus ocellatus]]'' (Oscar) Image:0gdtex_tut_2.png|''[[commons:Salmo salar|Salmo salar]]'' (Salmon Larva) Image:0gdtex_tut_3.png|''[[commons:Epinephelus lanceolatus|Epinephelus lanceolatus]]'' (Giant grouper) Image:0gdtex_tut_4.png|''[[commons:Pterois volitans|Pterois volitans]]'' (Red Lionfish) Image:0gdtex_tut_5.png|''[[commons:Macropodus opercularis|Macropodus opercularis]]'' (Paradise fish) Image:0gdtex_tut_6.png|''[[commons:Canthigaster valentini|Canthigaster valentini]]'' (Valentinni's sharpnose puffer) Image:0gdtex_tut_7.png|[[Image:POTY ribbon 2007.svg|25px]] ''[[commons:Dactylopterus volitans|Dactylopterus volitans]]'' (Flying gurnard) Image:0gdtex_tut_8.png|''[[commons:Semicossyphus pulcher|Semicossyphus pulcher]]'' (California Sheephead) Image:0gdtex_tut_9.png|''[[commons:Category:Pseudorasbora parva|Pseudorasbora parva]]'' (Topmouth gudgeon) Image:0gdtex_tut_10.png|''[[commons:Category:Pterois antennata|Pterois antennata]]'' (Antennata Lionfish) Image:0gdtex_tut_11.png|''[[commons:Novaculichthys taeniourus|Novaculichthys taeniourus]]'' Image:0gdtex_tut_12.png|''[[commons:Synchiropus splendidus|Synchiropus splendidus]]'' (Mandarin fish) Image:0gdtex_tut_13.png|''[[commons:Psetta maxima|Psetta maxima]]'' (Turbot) </gallery> 4d300174991e9d32738580defa57e1f6e930bd84 1ST READ.BIN 0 61 166 2020-01-10T05:04:17Z Unknown user 0 Created page with "'''1ST_READ.BIN''' (sometimes called '''0WINCEOS.BIN''', '''BOOTFILE.BIN''', etc.) is the main executable for Dreamcast software. There is no specific required filename, howev..." wikitext text/x-wiki '''1ST_READ.BIN''' (sometimes called '''0WINCEOS.BIN''', '''BOOTFILE.BIN''', etc.) is the main executable for Dreamcast software. There is no specific required filename, however the filename does need to be specified in [[IP.BIN]], and most developers simply follow the convention of naming it 1ST_READ.BIN. 43e7da0de7e0ab699891bf6bfe4227c752277567 File:0GDTEX Creation Tool.7z 6 62 167 2020-01-10T05:04:59Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 CD-ROM 0 63 168 2020-01-10T05:07:15Z Unknown user 0 Redirected page to [[MIL-CD]] wikitext text/x-wiki #REDIRECT [[MIL-CD]] e5010b41dbeb36f1945f6ae80ed05789c6100f17 MIL-CD 0 64 169 2020-01-10T05:10:38Z Unknown user 0 Created page with "'''MIL-CD''' is the name given to the Dreamcast format for loading code from a CD-ROM or CD-R. There were eight official MIL-CD releases, distributed in Japan only, all of whi..." wikitext text/x-wiki '''MIL-CD''' is the name given to the Dreamcast format for loading code from a CD-ROM or CD-R. There were eight official MIL-CD releases, distributed in Japan only, all of which were audio music CDs containing extra audiovisual content when loaded in a Dreamcast console. This format was reverse engineered by the community to load homebrew code and pirated software, as well as create independent, unofficial commercial game releases. e671cd9f2c856d9ea3631514829f5612266158f5 198 169 2020-01-10T15:49:56Z Unknown user 0 wikitext text/x-wiki '''MIL-CD''' is the name given to the Dreamcast format for loading code from a CD-ROM or CD-R. There were eight official MIL-CD releases, distributed in Japan only, all of which were audio music CDs containing extra audiovisual content when loaded in a Dreamcast console. This format was reverse engineered by the community to load homebrew code and pirated software, as well as create independent, unofficial commercial game releases. Additionally, it is now possible to make new custom Mil-CDs in the original intended format consisting of audio + video and playable on a Dreamcast. 3eef3dc40bdff1a1584c70b1971fc3a94c7310f9 HaydenKow 0 65 175 2020-01-10T05:38:34Z Unknown user 0 Created page with "'''HaydenKow''' ---- * Aliases: Hayden Kowalchuk, mrneo240, neo, HaydenKow * Develops in: C, C++, ASM, PHP == Dreamcast Software == * [[neoIP]]: Full open source [[IP.BIN]] r..." wikitext text/x-wiki '''HaydenKow''' ---- * Aliases: Hayden Kowalchuk, mrneo240, neo, HaydenKow * Develops in: C, C++, ASM, PHP == Dreamcast Software == * [[neoIP]]: Full open source [[IP.BIN]] replacement with a variety of options * [[nuQuake]]: OpenGL Port of glquake with 640x480 @ 60fps * [[gamejam]]: Multiplatform game engine/framework with Dreamcast being the main platform, used primarily for games but can be used for applications. == Desktop Software == * Windows ** PVieweR: View PVR images and convert to BMP ** CDDA Tools: Rips CDI image Tracks to WAV and optionally converts to FLAC ** PSOSS: Reads a .VMS save containing a Screenshot from Phantasy Star Online and converts to PNG * Web **DREAMCAST VMU ICONDATA CREATOR: Creates a Valid ICONDATA.VMS from any image with some customization b1fbeff70760982299325fe959550af25796a43a 176 175 2020-01-10T05:38:47Z Unknown user 0 wikitext text/x-wiki * Aliases: Hayden Kowalchuk, mrneo240, neo, HaydenKow * Develops in: C, C++, ASM, PHP == Dreamcast Software == * [[neoIP]]: Full open source [[IP.BIN]] replacement with a variety of options * [[nuQuake]]: OpenGL Port of glquake with 640x480 @ 60fps * [[gamejam]]: Multiplatform game engine/framework with Dreamcast being the main platform, used primarily for games but can be used for applications. == Desktop Software == * Windows ** PVieweR: View PVR images and convert to BMP ** CDDA Tools: Rips CDI image Tracks to WAV and optionally converts to FLAC ** PSOSS: Reads a .VMS save containing a Screenshot from Phantasy Star Online and converts to PNG * Web **DREAMCAST VMU ICONDATA CREATOR: Creates a Valid ICONDATA.VMS from any image with some customization d3eef45ecec643d29c0fbec6d7e87a207f038bb2 Boot process 0 20 180 92 2020-01-10T05:43:17Z Unknown user 0 Darc moved page [[Dreamcast Boot Process]] to [[Boot process]] wikitext text/x-wiki In general, the boot process is something like this:<br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # [[IP.BIN]] is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast scramble loads this binary from disc it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as [[DCLOAD-IP]] or [[DCLOAD-SERIAL]] bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL so that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. 66afa325ae198a4f34fd03da253165c7c5e8cb09 Dreamcast Boot Process 0 66 181 2020-01-10T05:43:17Z Unknown user 0 Darc moved page [[Dreamcast Boot Process]] to [[Boot process]] wikitext text/x-wiki #REDIRECT [[Boot process]] be628cc6514753cf3ad1133b098ec0b579392938 Media players 0 67 186 2020-01-10T06:14:44Z Unknown user 0 Created page with "== Commercial media players == * [[Blaze MP3]] * [[Pelican MP3]] * [[Dream VCD Player]] == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * Dream..." wikitext text/x-wiki == Commercial media players == * [[Blaze MP3]] * [[Pelican MP3]] * [[Dream VCD Player]] == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * [[DreamAMP]] * [[JPamp3]] * [[ToEleven]] * [[SIDPlay]] === Image viewers === * [[D.I.S.S.]] === Video players === * [[DC Movie Player]] * [[DCDivX]] * [[GypPlay]] * [[uDCDivX]] * [[VC/DC]] 7a6ce4326c9fae1b18689d13995960469401c6de User:Neo 2 68 193 2020-01-10T06:54:13Z Unknown user 0 Redirected page to [[HaydenKow]] wikitext text/x-wiki #REDIRECT [[HaydenKow]] a60919067d83566d6270855dc25a0f3e8f5333f5 User:Darc 2 69 194 2020-01-10T06:55:57Z Unknown user 0 Redirected page to [[Darc]] wikitext text/x-wiki #REDIRECT [[Darc]] afd9c497578a237b0125515f7b4091b708291bd6 Darc 0 70 195 2020-01-10T06:56:46Z Unknown user 0 Created page with "{{DISPLAYTITLE:darc}} '''darc''' is a Dreamcast enthusiast and operator of DCEmulation and dreamcast.wiki." wikitext text/x-wiki {{DISPLAYTITLE:darc}} '''darc''' is a Dreamcast enthusiast and operator of DCEmulation and dreamcast.wiki. 8025e5170b8ff972e82bb5b75c0e0447f16aab05 DreamPi 0 18 196 50 2020-01-10T07:48:53Z Unknown user 0 wikitext text/x-wiki DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. 2b45c1611646bdef3fe464bf31724893d8985947 Dumping GD-ROMs 0 6 197 23 2020-01-10T15:45:39Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a broadband adapter, the simplest way is using httpd-ack, which is available from here: https://www.gotwalls.com/ ---- might be worth writing a simple guide them linking to redump and dumpcast guides 22e2fc81daa700bf8cb8bd1d4826c1eb3c2610f3 205 197 2020-01-10T18:33:57Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). Do not use Dreamshell for dumping GD-ROMs as the ripper software in Dreamshell is unreliable. ---- might be worth writing a simple guide them linking to redump and dumpcast guides 4a277cd045e5b2ab277f4842cee44472374488e0 208 205 2020-01-10T18:38:43Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). Do not use Dreamshell for dumping GD-ROMs as the ripper software in Dreamshell is unreliable. 3cc9ef7853d3165f91f388a32b1ce7e0c46ca01d GLdc 0 24 199 76 2020-01-10T15:53:03Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [GLdc](https://github.com/Kazade/GLdc) is an OpenGL implementation for the Dreamcast that is actively developed by Kazade. MrNeo also contributed to the testing and optimisation of GLdc ## Features Supports most of the OpenGL 1.2 implementation. ## Known Issue Lighting performance is still being worked on. ## Projects built with GLdc * [[Simulant|Simulant engine]] * [[Summoning Signals]] * [[nuQuake]] ## Building GLdc ** Make sure you clone this repo in the `$KOS_BASE/addons` folder ** `cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git` Once the folder is cloned `cd GLdc && make defaultall && make create_kos_link` You can now link GLdc using `-lGLdc` 229a86a03b5bdb44152304eaa7f3512c887fab4e File:Windows CE boot screen.png 6 71 200 2020-01-10T17:46:49Z Unknown user 0 wikitext text/x-wiki Windows CE MR image being shown during Sega Dreamcast boot screen e2734e47377de6ef9dd4d18451fd53173ecfce8c File:Httpd-ack-20080711.zip 6 72 201 2020-01-10T18:28:03Z Unknown user 0 httpd-ack binary CDI wikitext text/x-wiki == Summary == httpd-ack binary CDI ef5bdac62785891d0d34468ad6bc37a7c06b5a71 MR image 0 73 202 2020-01-10T18:28:29Z Unknown user 0 Created page with "==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. File:Windows CE boot scree..." wikitext text/x-wiki ==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was commonly used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. Since IP.BIN is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== d0e99f6e4d64fa2fa671402a65c784c04d233768 206 202 2020-01-10T18:35:30Z Unknown user 0 /* About */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the Dreamcast application. Since IP.BIN is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== 9019d45751b8ba35dfc4373dd6fc0a8c8a0b0ff8 207 206 2020-01-10T18:38:37Z Unknown user 0 /* About */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or . Since IP.BIN is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== 8f2bf9d7c72a462882f7613e6ecc3ff57391310a IP.BIN 0 35 203 138 2020-01-10T18:29:20Z Unknown user 0 /* Bootstrap 1 */ wikitext text/x-wiki == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an [[MR Image]] * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * A custom [[MR Image]] can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== This is Generally where all the base setup code is kept so our binary has a known, and clean execution environment in which it starts. In [[Warez]] releases this is the area that is responsible for a very sneaky trick. The [[1ST_READ.BIN]] binary is kept as is on the disc, but then when scramble loaded by the bios (See [[Dreamcast_Boot_Process]] for further)) it will be unusable, so code was written to unscramble, the now ruined binary, in-place. The second part of this trick also reinitializes the [[GD-ROM]] drive and passes the [[HOLLY]] bios check so that the game may access the data on the disc and execute normally. ==== Other uses ==== * [[neoIP]] is a complete open source replacement for these bootstraps and is currently able to load: homebrew, official Katana and WINCE binaries from either a [[GD-ROM]] or [[CD-ROM]] developed by [[HaydenKow]] * [[IP.BIN Replacement]] This as far as I know is the first LEGAL ip.bin replacement for the dc, however it is pretty much untested. Developed by LiENUS ==References== <references/> 92fe0e325864524e6649d92cb2acf0f10b4100b4 File:Dcsdrip11.zip 6 74 204 2020-01-10T18:33:06Z Unknown user 0 SDRip CDI file for dumping GD-ROMs wikitext text/x-wiki == Summary == SDRip CDI file for dumping GD-ROMs f9ff5240e9b61374f6215a9b0097e9aedf26708c Talk:Dumping GD-ROMs 1 75 209 2020-01-10T18:38:58Z Unknown user 0 Created page with "might be worth writing a simple guide them linking to redump and dumpcast guides --~~~~" wikitext text/x-wiki might be worth writing a simple guide them linking to redump and dumpcast guides --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 10:38, 10 January 2020 (PST) f9bc60c934b56597a12463496a0bd17401cf1994 Talk:Dumping GD-ROMs 1 75 210 209 2020-01-10T18:40:40Z Unknown user 0 wikitext text/x-wiki might be worth writing a simple guide them linking to redump and dumpcast guides --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 10:38, 10 January 2020 (PST) At some point, I've been planning on writing a brand new master guide to dumping on DC including GD-R dumping. That'll become integrated with this section, is what I'm thinking [[User:Darc|Darc]] ([[User talk:Darc|talk]]) 10:40, 10 January 2020 (PST) f9fc0502591b72671833ed18689e03013c5ce8e1 Media players 0 67 211 186 2020-01-10T18:44:22Z Unknown user 0 /* Audio players */ wikitext text/x-wiki == Commercial media players == * [[Blaze MP3]] * [[Pelican MP3]] * [[Dream VCD Player]] == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * [[DreamAMP]] * [[JPamp3]] * [[ToEleven]] * [[SIDPlay]] *[[Dreammidi]] === Image viewers === * [[D.I.S.S.]] === Video players === * [[DC Movie Player]] * [[DCDivX]] * [[GypPlay]] * [[uDCDivX]] * [[VC/DC]] ca9978d4776947c13243e07179ac63bc535b1c1f 239 211 2020-01-10T21:47:55Z Unknown user 0 wikitext text/x-wiki == Commercial media players == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Blaze MP3]] | MP3 Player | |- | [[Pelican MP3]] | | |- | [[Dream VCD Player]] | | |} == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * [[DreamAMP]] * [[JPamp3]] * [[ToEleven]] * [[SIDPlay]] *[[Dreammidi]] === Image viewers === * [[D.I.S.S.]] === Video players === * [[DC Movie Player]] * [[DCDivX]] * [[GypPlay]] * [[uDCDivX]] * [[VC/DC]] 4c305ba474a634e68dc87cbcc7936661ed550436 MR image 0 73 212 207 2020-01-10T18:44:26Z Unknown user 0 /* About */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by Sega. Since IP.BIN is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== 35b1388abf3ecbec605c701e24a945b3323cc866 213 212 2020-01-10T18:45:49Z Unknown user 0 /* About */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since IP.BIN is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== f817db30b7ac4d5eee1c896b802c2f31083047cc 214 213 2020-01-10T18:48:37Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an IP.BIN file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== 6fa5d54ed1c980ebcafeb43df9d5bd3efdedca30 215 214 2020-01-10T18:48:52Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==Format Structure== ==Encoding== ==Decoding== 3fb5cb42c03299046c72501125da923aaba4cc2f 258 215 2020-01-10T22:21:46Z Unknown user 0 /* Format Structure */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==File Structure== ==Encoding== ==Decoding== 8a8a5f9ad203cd07fb9176be267f8bd73c9238d0 Freeware homebrew games 0 76 216 2020-01-10T18:58:45Z Unknown user 0 Created page with "=Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **DCQua..." wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Space Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[ArmoredCampaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[Clone Keen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[SonicRoboBlast2|Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 241cbd658276cb3d85fedc6cd6d6760826d0af67 Development 0 2 217 130 2020-01-10T18:59:28Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 14a00be4a15f634f007884a65c1da3d3660aee8d 244 217 2020-01-10T21:53:14Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Dan Potter's notes]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 650724f335d8968c1040f59355b7efeb09cc6aff 249 244 2020-01-10T21:57:32Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 4844bdfb18dfd1e3d4d6ff7f635e68fad734d969 261 249 2020-01-10T23:15:54Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] afe31c7e381279d9c1d4c4d47a07bf2a4aa711fb Dreamcast.wiki 0 1 218 192 2020-01-10T19:16:07Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == {| style="width:100%" ! style="width: 50%"|Console Hardware and Peripherals ! style="width: 50%"|Modifications |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] |} |} == Modifications == * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} fb999d23654bda7e0fdc1c9c40b5dc375cfef244 219 218 2020-01-10T19:16:19Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == {| style="width:100%" ! style="width: 50%"|Console Hardware and Peripherals ! style="width: 50%"|Modifications |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] |} |} == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 7ae18978fa3ad8f806a95185bc4dc0175a0273e6 220 219 2020-01-10T19:18:02Z Unknown user 0 /* Hardware */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] == Repair == * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} bda15cfac0fbc4ed785057205a7e82cc86f9b870 221 220 2020-01-10T19:18:13Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 2d6dd075f7d86acef134123c037863654ddc713f 222 221 2020-01-10T19:21:46Z Unknown user 0 /* Software */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} == Technical Pages == * [[Memory map]] * [[Boot process]] * [[IP.BIN]] __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 06c8f4f9c7b83c457a48ca15542230e7e16bca79 223 222 2020-01-10T19:22:00Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * [[Indie games]] * [[Freeware homebrew games]] * [[Emulating other systems on Dreamcast]] * [[Media players]] * [[Other Dreamcast software]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 8a01eaed0e40c0ba8dcce7255e01353e646d80fc 224 223 2020-01-10T19:38:53Z Unknown user 0 /* Software */ wikitext text/x-wiki dreamcast.wiki is a compendium of Dreamcast-related knowledge. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 2efa16b567887e17f07def87d83e5881f1cc8a01 225 224 2020-01-10T20:54:38Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 765d34ba1664bf6da54907b1e9a4643b3f50d26a 227 225 2020-01-10T21:01:58Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} dba04c8dee2e95d3a9f3393cc597efde3c7e17dc 229 227 2020-01-10T21:10:16Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 16c12544462e1faaf1602f419512fb16bf6cd081 230 229 2020-01-10T21:12:08Z Unknown user 0 /* Software */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 78ee1730babaa769ef6fa2dd363aba5b2c35c25f 231 230 2020-01-10T21:14:06Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} b796e8cf1db9035996a1d8c8a3c018ecb5f0f377 232 231 2020-01-10T21:15:15Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} a24a8c06abee90a083396375b62f13fbefc1f277 233 232 2020-01-10T21:16:35Z Unknown user 0 /* Software */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 7857a67006430aa3bed2cf78805c2ca38b61387d 234 233 2020-01-10T21:36:40Z Unknown user 0 /* Software */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]] * [[BIOS revisions]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 6c27bb5f161f5713d936c7e3f3f1c72bc680aac5 235 234 2020-01-10T21:37:53Z Unknown user 0 /* Software */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]] * [[BIOS]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} bd10aeb19907e60a37bb7bc519e43b63904d8457 242 235 2020-01-10T21:51:59Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] {{DCWiki:About}} == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]] * [[BIOS]] * [[VMU development]] |} |} == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 5b22d41290dc9b0e7730bc853dfd2a2451050269 247 242 2020-01-10T21:53:53Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] {{DCWiki:About}} == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] {{DCWiki:Software}} {{DCWiki:Hardware}} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 1a436c2f4b1a51fc9fa7be011cb38e015d632428 File:Dreamcast.jpg 6 77 226 2020-01-10T21:00:18Z Unknown user 0 Just a picture of the good old Dreamcast and a controller with VMU inserted. wikitext text/x-wiki == Summary == Just a picture of the good old Dreamcast and a controller with VMU inserted. 7d8d9f66e685df2a318e7559a7e9c10b956d7c7d Serial SD card adapter 0 15 228 46 2020-01-10T21:05:39Z Unknown user 0 wikitext text/x-wiki The serial SD card adapter is a community-designed peripheral that allows software to access an SD card for reading and writing through the Dreamcast's serial connector. Files can be accessed and manipulated using [[DreamShell]]. Code and games can be executed from the SD card, but because access is limited by the slow serial connectivity, running commercial games in this way is typically slow and buggy. Gamers looking to play games via SD card should look for an [[Optical drive replacements|optical drive replacement]] instead. 8d857aeb2f3dfac1e1b667d3cd596b9c2fa83198 Indie games 0 13 236 89 2020-01-10T21:43:59Z Unknown user 0 /* Active Development */ wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |} == Unknown Status == == Inactive == == Released == {| class="wikitable" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |} 3467c9b9cb5f0b191e137cc145250ea24ee89d08 237 236 2020-01-10T21:44:34Z Unknown user 0 wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |} e6f3fc0484175568744cdf235a348ab9038fec4b BIOS 0 78 238 2020-01-10T21:44:58Z Unknown user 0 Created page with "The Sega Dreamcast BIOS has several known revisions: * v1.004 or MPR-21068, found in Japanese consoles only * v1.01c or MPR-21871, found in PAL consoles * v1.01d or MPR-21931..." wikitext text/x-wiki The Sega Dreamcast BIOS has several known revisions: * v1.004 or MPR-21068, found in Japanese consoles only * v1.01c or MPR-21871, found in PAL consoles * v1.01d or MPR-21931 or MPR-21933, found in consoles worldwide ** The [[Treamcast]] console uses a hacked version of this firmware with Chinese support. * v1.022 or MPR-23588, found in U.S. and Japanese consoles ** Consoles with this revision BIOS have [[MIL-CD]] booting disabled. 6f6f3ebc8d15b8bd24333ae32fe5ef827af2831a Treamcast 0 79 240 2020-01-10T21:49:26Z Unknown user 0 Created page with "'''Treamcast''' was a Chinese company creating unlicensed aftermarket Dreamcast products, including the "Treamcast" console, a rebranded Dreamcast console with a built-in port..." wikitext text/x-wiki '''Treamcast''' was a Chinese company creating unlicensed aftermarket Dreamcast products, including the "Treamcast" console, a rebranded Dreamcast console with a built-in portable screen. The console was not technically a clone since it used mostly salvaged Dreamcast parts with a new case featuring a built-in screen. The console featured a hacked [[BIOS]] with Chinese language support. Treamcast also made several accessories and peripherals for the Dreamcast. ea270ed59cc6b5037757a99889a19a28bc7f14ba DCWiki:About 4 80 241 2020-01-10T21:51:40Z Unknown user 0 Created page with "dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First s..." wikitext text/x-wiki dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. 7dee9dd9da9263fe28b32cd16f8ce54d844db23e DCWiki:Software 4 81 243 2020-01-10T21:52:57Z Unknown user 0 Created page with "== Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:t..." wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]] * [[BIOS]] * [[VMU development]] |} |} 3abb60c8281a12d9e84bc4f80cc442f2da985bff DCWiki:Hardware 4 82 245 2020-01-10T21:53:30Z Unknown user 0 Created page with "== Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| *..." wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} 2de09ef7d372ef41603b987c6f1649ac7b155aa0 MediaWiki:Sidebar 8 10 248 77 2020-01-10T21:54:25Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** forums-url|DCEmulation forums ** simulant-discord-url|Simulant Discord ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair * wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES 3942e0fb12a064872b481be1ebb0cebed95baeb1 Fast SH4 Vertex Processing 0 84 250 2020-01-10T21:58:06Z Unknown user 0 Created page with "{{MARKDOWN}} [Original source](http://yam.20to4.net/dreamcast/hints/index.html) ## A few programming hints I thought they are worth sharing. Vector Math Instructions Cache St..." wikitext text/x-wiki {{MARKDOWN}} [Original source](http://yam.20to4.net/dreamcast/hints/index.html) ## A few programming hints I thought they are worth sharing. Vector Math Instructions Cache Store Queues Optimizing TnL Loops ## Vector Math Instructions The SH4 CPU featrues some nice builtin math operations. I saw some people trying to speed up their code by using approximations with integer codes and other tricks. That may work but on the SH4 good code that makes use of the builtin instructions will outperform in the most situations. There is not much sense in trying to replace that functions at all since they are already pretty fast. ### `FIPR` Computes the dot product of two 4D vectors `x1*x2 + y1*y2 + z1*z2 + w1*w2` Often used in lighting formulas. ### `FTRV` Muliplies a 4x4 matrix with a 4D vector Usually used to transform vertices, but can also be used to compute "a * b + c" for four floats in parallel. However, the FMAC may perform better in particular situations because the matrix needs to be setup in a special way. ### `FSRRA` Approximates `1.0f / sqrt (x)` Usually used to normalize a vector ### `FSCA` Approximates the sine and cosine. Comes in handy when constructing rotation matrices. This one takes the angle as an integer in the range 0...32767 so it's best to redefine angle representations throughout the whole code so that an angle of PI = 16384 or something. This would save the required conversion (range scale and truncation to integer). ### `FSQRT` Computes `sqrt (x)` This is actually not a special instruction but it's there and comes in handy sometimes although it's slower than FSRRA so rewrite your math formulas (e.g. range falloff lighting) and try to use FSRRA where applicable instead. ### `FMAC` Computes `a * b + c` This is as fast as normal float addition, subtraction or multiplication, so basically you pay one and get another operation for free. Comes in handy when doing linear interpolation (polygon clipping, table lookups etc). ### `FMOV` (64 bit) This instruction is very important since it can access the second banked set of the FPU registers that are normally used to hold the vector transformation matrix. It's best to avoid switching the fmov mode very often, so rearrange your data layout. It also requires the data to be 64 bit aligned (8 bytes). ### Cache The cache is very very important. It is so important that it may either save your day or screw up everything. First of all it is important to understand how the cache works. It is a direct mapped cache, i.e. the cache lines are mapped directly onto the addresses of the memory and since it's only 16 KB small the memory at address (n) is mapped onto the same cache line as the location at address (n + 1024*16) which will result in a cache miss. So it's best to avoid such situations which is not always possible especially when working with large amounts of data, e.g. vertex data. That's where the powerful cache control instructions come in... ### `PREF` Prefetches a cache line for the specified address Use this to prefetch the next element in processing loops for large data buffers. The prefetch delay can be hidden by prefetching the next element at the beginning of the loop. ### `OCBWB` Writes back a cache line This one is often used when cache content and memory content need to be synchronized explicitely for DMA transfers since the DMA controllers operate directly on memory. ### `OCBI` Invalidates a cache line This is also used often with DMA functions before reading a memory area that had just been rewritten by a DMA controller. Another way would be to access the memory area as uncached but this might slow down everything. ### `OCBP` Purges a cache line (write back & invalidate) Use this one after your processing loop definitely has finished its operations for one element. The effect is very similar to the store queues except that you cannot read anything from the store queue lines and can write only 32 or 64 bits at once. ### `MOVCA.L` Allocates a cache line for the specified address This one is very important when processing large buffers. While the OCBP instruction can be left out wihtout any performance drops this is does not apply for MOVCA.L. When processing large buffers you often have an input buffer and an output buffer. The input buffer is read, something is done with the elements and they are stored into the output buffer. Without MOVCA.L a store to the output buffer would cause the cache to read a cache line from the output buffer and redirect the store into the cache. This is a total waste, because most of time every byte of the output buffer is only rewritten with new content. That's what the MOVCA.L is for. It tells the cache to reserve a cache line without fetching memory. But be careful this may cause data corruption. There is another cache feature which makes it possible to use half of the operand cache (i.e. 8 KB) as scratchpad RAM. This may be used to hold transformation loop parameters like matrices or something but it also halves the operand cache size which may decrease overall performance of the code. ### Store Queues These come in handy when flushing vertices to the graphics hardware or to memory. Basically all they are for is batching up 32 bytes of data and flushing it to some location. The store queues can be used to write to main memory but they bypass the cache thus cache synchronization may become an issue. There are some benefits when using the store queues, among them there are two which I think are worth mentioning. First there are two of them each 32 bytes in size and both operate independently, i.e. you can instruct one store queue to flush its contents and write to the other at the same time without stalling the program code. Then there is another nice feature which I call "data cloning". Sometimes you need to clone data for whatever reason. For one normal store and one cloning operation this implies two reads and two writes per element. With appropriate pointer mapping setup you can reduce this to one read and two writes which will boost the performance of your code. The trick is easy to do. All you have to do is telling a store queue to flush with two different addresses. The store queue number is indicated by bit 6 of the flushing address and the other upper bits are the raw address where the store queue content is flushed to. However, each flush instruction will stall the code until the concerned store queue has finished a previous flush operation. So it's best to do something else between two flush instructions. Notice also that the store queues can be used in conjunction with the MMU for mapping the store queue address space to different pieces of hardware which eliminates the need to set up the QARC0 / QARC1 registers. ### Optimizing TnL Loops This is probably one of the most frequent optimization topics. Always remember the 20-80 rule: 80 percent of the time is spent in 20 percent of the code. Thus first of all identify your bottle necks. For the most cases this will be the graphics routines, or more precicely the transform and lighting part of the graphics routines, since on Dreamcast this stuff is done by the CPU. When doing "complex" transformation and lighting you may get very large loops that do a lot of operations per vertex. Of course it's best to avoid any operations in the first place (culling) but eventually you will have to compute the lighting intensities for 3 light sources, compute the bumpmapping parameters, apply 8 skinning matrices or whatever you are going to do with one vertex. Let's take a simple example which is supposed to apply diffuse and specular lighting to a vertex, transforming the vertex and storing it in a buffer. This may look as follows: ``` do { fetch vertex apply diffuse lighting ((N * L) * material diffuse color * light color) apply specular lighting (pow ((N * H), material shininess) * material specular color * light color) clamp and pack the lighting result to packed 32 bit ARGB apply transformation (matrix) * (x,y,z,1) apply perspective divide (1/w) write back vertex } while (-- count); ``` Now add a few more things and you will get quite a big loop and you will run out of FPU registers for sure. Additionally this code is subject to bad pipelining since most of the operatations depend on the results of previous operations. So there are a few things we better do in a different way. Normally each vertex does not depend on adjacent vertices in the buffer. The operations applied are the same for each vertex. If we had a lot of CPU cores as the Cell Processor will we could do some parallel processing, but we don't. Still there is a way to speed things up by processing two vertices at a time, but this will work only if there are enough FPU registers left to hold at least some parts of a second vertex. What we do is simply breaking up the loop in independent and simple steps: - apply diffuse lighting - apply specular lighting - clamp and pack lighting result - apply transformation and perspective divide Thus we'll get something like... ``` do { fetch vertex parts apply diffuse lighting store temporary results } while (-- count); do { fetch vertex parts apply specular lighting store temporary results } while (-- count); do { fetch temporary results clamp and pack lighting result store packed values } while (-- count); do { fetch vertex parts apply transformation apply perspective divide store results } while (-- count); ``` Now we have small and simple loops that can be pipelined much better since there are more spare registers left. Also the loops can be applied in any order and in any combination making the code more flexible. For instance, if you don't need specular lighting then just don't call the specular lighting loop, that's it. The trick now is to run the small loops not over the whole buffer at once but over smaller blocks of the buffer. This way the currently processed vertices will be kept in the cache for each of the many loop iterations. As to my experience a block size of 32 vertices gives the best performance. Decreasing the value may introduce loop startup or function call overhead. Increasing the value may also increase cache misses. It's the same as with network packet sizes: you have to try a little bit to find the best value. ee1e8e9390815e2d6e9dd7a59caa66fea5c24240 251 250 2020-01-10T21:58:27Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [Original source](http://yam.20to4.net/dreamcast/hints/index.html) ## A few programming hints I thought they are worth sharing. Vector Math Instructions Cache Store Queues Optimizing TnL Loops ## Vector Math Instructions The SH4 CPU featrues some nice builtin math operations. I saw some people trying to speed up their code by using approximations with integer codes and other tricks. That may work but on the SH4 good code that makes use of the builtin instructions will outperform in the most situations. There is not much sense in trying to replace that functions at all since they are already pretty fast. ### `FIPR` Computes the dot product of two 4D vectors `x1*x2 + y1*y2 + z1*z2 + w1*w2` Often used in lighting formulas. ### `FTRV` Muliplies a 4x4 matrix with a 4D vector Usually used to transform vertices, but can also be used to compute "a * b + c" for four floats in parallel. However, the FMAC may perform better in particular situations because the matrix needs to be setup in a special way. ### `FSRRA` Approximates `1.0f / sqrt (x)` Usually used to normalize a vector ### `FSCA` Approximates the sine and cosine. Comes in handy when constructing rotation matrices. This one takes the angle as an integer in the range 0...32767 so it's best to redefine angle representations throughout the whole code so that an angle of PI = 16384 or something. This would save the required conversion (range scale and truncation to integer). ### `FSQRT` Computes `sqrt (x)` This is actually not a special instruction but it's there and comes in handy sometimes although it's slower than FSRRA so rewrite your math formulas (e.g. range falloff lighting) and try to use FSRRA where applicable instead. ### `FMAC` Computes `a * b + c` This is as fast as normal float addition, subtraction or multiplication, so basically you pay one and get another operation for free. Comes in handy when doing linear interpolation (polygon clipping, table lookups etc). ### `FMOV` (64 bit) This instruction is very important since it can access the second banked set of the FPU registers that are normally used to hold the vector transformation matrix. It's best to avoid switching the fmov mode very often, so rearrange your data layout. It also requires the data to be 64 bit aligned (8 bytes). ## Cache The cache is very very important. It is so important that it may either save your day or screw up everything. First of all it is important to understand how the cache works. It is a direct mapped cache, i.e. the cache lines are mapped directly onto the addresses of the memory and since it's only 16 KB small the memory at address (n) is mapped onto the same cache line as the location at address (n + 1024*16) which will result in a cache miss. So it's best to avoid such situations which is not always possible especially when working with large amounts of data, e.g. vertex data. That's where the powerful cache control instructions come in... ### `PREF` Prefetches a cache line for the specified address Use this to prefetch the next element in processing loops for large data buffers. The prefetch delay can be hidden by prefetching the next element at the beginning of the loop. ### `OCBWB` Writes back a cache line This one is often used when cache content and memory content need to be synchronized explicitely for DMA transfers since the DMA controllers operate directly on memory. ### `OCBI` Invalidates a cache line This is also used often with DMA functions before reading a memory area that had just been rewritten by a DMA controller. Another way would be to access the memory area as uncached but this might slow down everything. ### `OCBP` Purges a cache line (write back & invalidate) Use this one after your processing loop definitely has finished its operations for one element. The effect is very similar to the store queues except that you cannot read anything from the store queue lines and can write only 32 or 64 bits at once. ### `MOVCA.L` Allocates a cache line for the specified address This one is very important when processing large buffers. While the OCBP instruction can be left out wihtout any performance drops this is does not apply for MOVCA.L. When processing large buffers you often have an input buffer and an output buffer. The input buffer is read, something is done with the elements and they are stored into the output buffer. Without MOVCA.L a store to the output buffer would cause the cache to read a cache line from the output buffer and redirect the store into the cache. This is a total waste, because most of time every byte of the output buffer is only rewritten with new content. That's what the MOVCA.L is for. It tells the cache to reserve a cache line without fetching memory. But be careful this may cause data corruption. There is another cache feature which makes it possible to use half of the operand cache (i.e. 8 KB) as scratchpad RAM. This may be used to hold transformation loop parameters like matrices or something but it also halves the operand cache size which may decrease overall performance of the code. ## Store Queues These come in handy when flushing vertices to the graphics hardware or to memory. Basically all they are for is batching up 32 bytes of data and flushing it to some location. The store queues can be used to write to main memory but they bypass the cache thus cache synchronization may become an issue. There are some benefits when using the store queues, among them there are two which I think are worth mentioning. First there are two of them each 32 bytes in size and both operate independently, i.e. you can instruct one store queue to flush its contents and write to the other at the same time without stalling the program code. Then there is another nice feature which I call "data cloning". Sometimes you need to clone data for whatever reason. For one normal store and one cloning operation this implies two reads and two writes per element. With appropriate pointer mapping setup you can reduce this to one read and two writes which will boost the performance of your code. The trick is easy to do. All you have to do is telling a store queue to flush with two different addresses. The store queue number is indicated by bit 6 of the flushing address and the other upper bits are the raw address where the store queue content is flushed to. However, each flush instruction will stall the code until the concerned store queue has finished a previous flush operation. So it's best to do something else between two flush instructions. Notice also that the store queues can be used in conjunction with the MMU for mapping the store queue address space to different pieces of hardware which eliminates the need to set up the QARC0 / QARC1 registers. ## Optimizing TnL Loops This is probably one of the most frequent optimization topics. Always remember the 20-80 rule: 80 percent of the time is spent in 20 percent of the code. Thus first of all identify your bottle necks. For the most cases this will be the graphics routines, or more precicely the transform and lighting part of the graphics routines, since on Dreamcast this stuff is done by the CPU. When doing "complex" transformation and lighting you may get very large loops that do a lot of operations per vertex. Of course it's best to avoid any operations in the first place (culling) but eventually you will have to compute the lighting intensities for 3 light sources, compute the bumpmapping parameters, apply 8 skinning matrices or whatever you are going to do with one vertex. Let's take a simple example which is supposed to apply diffuse and specular lighting to a vertex, transforming the vertex and storing it in a buffer. This may look as follows: ``` do { fetch vertex apply diffuse lighting ((N * L) * material diffuse color * light color) apply specular lighting (pow ((N * H), material shininess) * material specular color * light color) clamp and pack the lighting result to packed 32 bit ARGB apply transformation (matrix) * (x,y,z,1) apply perspective divide (1/w) write back vertex } while (-- count); ``` Now add a few more things and you will get quite a big loop and you will run out of FPU registers for sure. Additionally this code is subject to bad pipelining since most of the operatations depend on the results of previous operations. So there are a few things we better do in a different way. Normally each vertex does not depend on adjacent vertices in the buffer. The operations applied are the same for each vertex. If we had a lot of CPU cores as the Cell Processor will we could do some parallel processing, but we don't. Still there is a way to speed things up by processing two vertices at a time, but this will work only if there are enough FPU registers left to hold at least some parts of a second vertex. What we do is simply breaking up the loop in independent and simple steps: - apply diffuse lighting - apply specular lighting - clamp and pack lighting result - apply transformation and perspective divide Thus we'll get something like... ``` do { fetch vertex parts apply diffuse lighting store temporary results } while (-- count); do { fetch vertex parts apply specular lighting store temporary results } while (-- count); do { fetch temporary results clamp and pack lighting result store packed values } while (-- count); do { fetch vertex parts apply transformation apply perspective divide store results } while (-- count); ``` Now we have small and simple loops that can be pipelined much better since there are more spare registers left. Also the loops can be applied in any order and in any combination making the code more flexible. For instance, if you don't need specular lighting then just don't call the specular lighting loop, that's it. The trick now is to run the small loops not over the whole buffer at once but over smaller blocks of the buffer. This way the currently processed vertices will be kept in the cache for each of the many loop iterations. As to my experience a block size of 32 vertices gives the best performance. Decreasing the value may introduce loop startup or function call overhead. Increasing the value may also increase cache misses. It's the same as with network packet sizes: you have to try a little bit to find the best value. 39cc743a0d1732940e207133967a0e7ca164db9f 253 251 2020-01-10T21:58:40Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} [Original source](http://yam.20to4.net/dreamcast/hints/index.html) ## Vector Math Instructions The SH4 CPU featrues some nice builtin math operations. I saw some people trying to speed up their code by using approximations with integer codes and other tricks. That may work but on the SH4 good code that makes use of the builtin instructions will outperform in the most situations. There is not much sense in trying to replace that functions at all since they are already pretty fast. ### `FIPR` Computes the dot product of two 4D vectors `x1*x2 + y1*y2 + z1*z2 + w1*w2` Often used in lighting formulas. ### `FTRV` Muliplies a 4x4 matrix with a 4D vector Usually used to transform vertices, but can also be used to compute "a * b + c" for four floats in parallel. However, the FMAC may perform better in particular situations because the matrix needs to be setup in a special way. ### `FSRRA` Approximates `1.0f / sqrt (x)` Usually used to normalize a vector ### `FSCA` Approximates the sine and cosine. Comes in handy when constructing rotation matrices. This one takes the angle as an integer in the range 0...32767 so it's best to redefine angle representations throughout the whole code so that an angle of PI = 16384 or something. This would save the required conversion (range scale and truncation to integer). ### `FSQRT` Computes `sqrt (x)` This is actually not a special instruction but it's there and comes in handy sometimes although it's slower than FSRRA so rewrite your math formulas (e.g. range falloff lighting) and try to use FSRRA where applicable instead. ### `FMAC` Computes `a * b + c` This is as fast as normal float addition, subtraction or multiplication, so basically you pay one and get another operation for free. Comes in handy when doing linear interpolation (polygon clipping, table lookups etc). ### `FMOV` (64 bit) This instruction is very important since it can access the second banked set of the FPU registers that are normally used to hold the vector transformation matrix. It's best to avoid switching the fmov mode very often, so rearrange your data layout. It also requires the data to be 64 bit aligned (8 bytes). ## Cache The cache is very very important. It is so important that it may either save your day or screw up everything. First of all it is important to understand how the cache works. It is a direct mapped cache, i.e. the cache lines are mapped directly onto the addresses of the memory and since it's only 16 KB small the memory at address (n) is mapped onto the same cache line as the location at address (n + 1024*16) which will result in a cache miss. So it's best to avoid such situations which is not always possible especially when working with large amounts of data, e.g. vertex data. That's where the powerful cache control instructions come in... ### `PREF` Prefetches a cache line for the specified address Use this to prefetch the next element in processing loops for large data buffers. The prefetch delay can be hidden by prefetching the next element at the beginning of the loop. ### `OCBWB` Writes back a cache line This one is often used when cache content and memory content need to be synchronized explicitely for DMA transfers since the DMA controllers operate directly on memory. ### `OCBI` Invalidates a cache line This is also used often with DMA functions before reading a memory area that had just been rewritten by a DMA controller. Another way would be to access the memory area as uncached but this might slow down everything. ### `OCBP` Purges a cache line (write back & invalidate) Use this one after your processing loop definitely has finished its operations for one element. The effect is very similar to the store queues except that you cannot read anything from the store queue lines and can write only 32 or 64 bits at once. ### `MOVCA.L` Allocates a cache line for the specified address This one is very important when processing large buffers. While the OCBP instruction can be left out wihtout any performance drops this is does not apply for MOVCA.L. When processing large buffers you often have an input buffer and an output buffer. The input buffer is read, something is done with the elements and they are stored into the output buffer. Without MOVCA.L a store to the output buffer would cause the cache to read a cache line from the output buffer and redirect the store into the cache. This is a total waste, because most of time every byte of the output buffer is only rewritten with new content. That's what the MOVCA.L is for. It tells the cache to reserve a cache line without fetching memory. But be careful this may cause data corruption. There is another cache feature which makes it possible to use half of the operand cache (i.e. 8 KB) as scratchpad RAM. This may be used to hold transformation loop parameters like matrices or something but it also halves the operand cache size which may decrease overall performance of the code. ## Store Queues These come in handy when flushing vertices to the graphics hardware or to memory. Basically all they are for is batching up 32 bytes of data and flushing it to some location. The store queues can be used to write to main memory but they bypass the cache thus cache synchronization may become an issue. There are some benefits when using the store queues, among them there are two which I think are worth mentioning. First there are two of them each 32 bytes in size and both operate independently, i.e. you can instruct one store queue to flush its contents and write to the other at the same time without stalling the program code. Then there is another nice feature which I call "data cloning". Sometimes you need to clone data for whatever reason. For one normal store and one cloning operation this implies two reads and two writes per element. With appropriate pointer mapping setup you can reduce this to one read and two writes which will boost the performance of your code. The trick is easy to do. All you have to do is telling a store queue to flush with two different addresses. The store queue number is indicated by bit 6 of the flushing address and the other upper bits are the raw address where the store queue content is flushed to. However, each flush instruction will stall the code until the concerned store queue has finished a previous flush operation. So it's best to do something else between two flush instructions. Notice also that the store queues can be used in conjunction with the MMU for mapping the store queue address space to different pieces of hardware which eliminates the need to set up the QARC0 / QARC1 registers. ## Optimizing TnL Loops This is probably one of the most frequent optimization topics. Always remember the 20-80 rule: 80 percent of the time is spent in 20 percent of the code. Thus first of all identify your bottle necks. For the most cases this will be the graphics routines, or more precicely the transform and lighting part of the graphics routines, since on Dreamcast this stuff is done by the CPU. When doing "complex" transformation and lighting you may get very large loops that do a lot of operations per vertex. Of course it's best to avoid any operations in the first place (culling) but eventually you will have to compute the lighting intensities for 3 light sources, compute the bumpmapping parameters, apply 8 skinning matrices or whatever you are going to do with one vertex. Let's take a simple example which is supposed to apply diffuse and specular lighting to a vertex, transforming the vertex and storing it in a buffer. This may look as follows: ``` do { fetch vertex apply diffuse lighting ((N * L) * material diffuse color * light color) apply specular lighting (pow ((N * H), material shininess) * material specular color * light color) clamp and pack the lighting result to packed 32 bit ARGB apply transformation (matrix) * (x,y,z,1) apply perspective divide (1/w) write back vertex } while (-- count); ``` Now add a few more things and you will get quite a big loop and you will run out of FPU registers for sure. Additionally this code is subject to bad pipelining since most of the operatations depend on the results of previous operations. So there are a few things we better do in a different way. Normally each vertex does not depend on adjacent vertices in the buffer. The operations applied are the same for each vertex. If we had a lot of CPU cores as the Cell Processor will we could do some parallel processing, but we don't. Still there is a way to speed things up by processing two vertices at a time, but this will work only if there are enough FPU registers left to hold at least some parts of a second vertex. What we do is simply breaking up the loop in independent and simple steps: - apply diffuse lighting - apply specular lighting - clamp and pack lighting result - apply transformation and perspective divide Thus we'll get something like... ``` do { fetch vertex parts apply diffuse lighting store temporary results } while (-- count); do { fetch vertex parts apply specular lighting store temporary results } while (-- count); do { fetch temporary results clamp and pack lighting result store packed values } while (-- count); do { fetch vertex parts apply transformation apply perspective divide store results } while (-- count); ``` Now we have small and simple loops that can be pipelined much better since there are more spare registers left. Also the loops can be applied in any order and in any combination making the code more flexible. For instance, if you don't need specular lighting then just don't call the specular lighting loop, that's it. The trick now is to run the small loops not over the whole buffer at once but over smaller blocks of the buffer. This way the currently processed vertices will be kept in the cache for each of the many loop iterations. As to my experience a block size of 32 vertices gives the best performance. Decreasing the value may introduce loop startup or function call overhead. Increasing the value may also increase cache misses. It's the same as with network packet sizes: you have to try a little bit to find the best value. 134067918f68cff8baf8ed481252ec722e0c2b00 File:Gcc asm sh4 tips.txt 6 86 254 2020-01-10T22:03:05Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Modem 0 87 259 2020-01-10T22:30:54Z Unknown user 0 Created page with "The Dreamcast console came packed with a 33.6K or 56K modem in the vast majority of configurations available worldwide. There is a good reference on the hardware revisions [ht..." wikitext text/x-wiki The Dreamcast console came packed with a 33.6K or 56K modem in the vast majority of configurations available worldwide. There is a good reference on the hardware revisions [http://users.skynet.be/t_chan/dc/mylist.htm here]. 59edb06a5b462d03f0871f9f355e3f8525800344 G2 bus 0 88 260 2020-01-10T22:33:40Z Unknown user 0 Created page with "The G2 bus is the high speed communications bus used for add-on accessories like the modem, network adapters, karaoke deck, etc. Hardware hackers have prototyped new hardware..." wikitext text/x-wiki The G2 bus is the high speed communications bus used for add-on accessories like the modem, network adapters, karaoke deck, etc. Hardware hackers have prototyped new hardware like ethernet adapters and USB controllers using the G2 bus. b033d505404b445017c0a707da40df6dd72700f5 Coder's cable 0 90 264 2020-01-10T23:23:09Z Unknown user 0 Created page with "The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host de..." wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). 26b1457dbcb3ffbb31b0241170d3c95c5be600aa DCWiki:Stub 4 91 265 2020-01-11T00:17:29Z Unknown user 0 Created page with "''This page is a stub page. It needs to be expanded with more detail. If you know more information about this topic, please sign up and contribute to dreamcast.wiki!''" wikitext text/x-wiki ''This page is a stub page. It needs to be expanded with more detail. If you know more information about this topic, please sign up and contribute to dreamcast.wiki!'' 9dee4b3ee1ed074bdb1c109d3356e429893a54cd A/V connectivity 0 8 266 35 2020-01-11T00:18:01Z Unknown user 0 wikitext text/x-wiki The Dreamcast natively supports RF video, composite video, S-video, 15KHz RGB video ("RGB SCART"), and 31KHZ RGBHV ("VGA") output. The RGB mode and VGA mode do not work for all official game titles. See [[Video mode compatibility list|the compatibility list]] for more details. Aftermarket cables containing circuits with YPbPr conversion hardware can be purchased or created. The Dreamcast can also be [[DCHDMI|modified to support HDMI output]]. {{DCWiki:Stub}} ee7363e956a29ab0a411df38f9cd2bc8891ae441 G2 bus 0 88 267 260 2020-01-11T00:18:11Z Unknown user 0 wikitext text/x-wiki The G2 bus is the high speed communications bus used for add-on accessories like the modem, network adapters, karaoke deck, etc. Hardware hackers have prototyped new hardware like ethernet adapters and USB controllers using the G2 bus. {{DCWiki:Stub}} 3193e0421f551f9f99ab791432636ffcd2de1cf1 Broadband adapter 0 5 268 129 2020-01-11T00:18:24Z Unknown user 0 wikitext text/x-wiki The Dreamcast Broadband adapter ("'''BBA'''") is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a somewhat rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. A program loader called DCLOAD-IP<ref>https://github.com/sizious/dcload-ip</ref> is also designed for use with it to aid in Dreamcast development. {{DCWiki:Stub}} 45fb90bb4a98c3aa950e4c2ed2ffa6579b6e62a5 LAN adapter 0 31 269 103 2020-01-11T00:18:36Z Unknown user 0 wikitext text/x-wiki The Dreamcast LAN adapter (not to be confused with the superior [[Broadband adapter]]) is a Japanese-only peripheral that connects to the [[G2 bus]] and provides the Dreamcast with 10mbps network connectivity via a Fujitsu MB86967 chip. The only official software that works with the LAN adapter is the Dream Passport for LAN web browser. No official games from any region are compatible with the LAN adapter. Homebrew software that is compatible with the Broadband adapter is also compatible with the LAN adapter, however, except that software is uncommonly tested with the adapter due to its rarity. {{DCWiki:Stub}} 115d2df4bb4779e27bfe5306f4c7854b79d2dd6a Zip drive 0 29 270 101 2020-01-11T00:18:46Z Unknown user 0 wikitext text/x-wiki The Dreamcast Zip drive was a planned, unreleased upgrade for the Dreamcast console. It would have connected to the bottom of the Dreamcast using the [[G2 bus]] connector, similar to the [[Dreamcast Karaoke]] unit. It would have added a Zip disk drive as well as a USB port to the Dreamcast. {{DCWiki:Stub}} e0780d9e665363f2644625a7eaed1a7a6aeb5f41 Modem 0 87 271 259 2020-01-11T00:18:59Z Unknown user 0 wikitext text/x-wiki The Dreamcast console came packed with a 33.6K or 56K modem in the vast majority of configurations available worldwide. There is a good reference on the hardware revisions [http://users.skynet.be/t_chan/dc/mylist.htm here]. {{DCWiki:Stub}} e93493ffb4f7e46274c5548040c11a44fc2efe46 MIDI adapter 0 30 272 102 2020-01-11T00:19:08Z Unknown user 0 wikitext text/x-wiki The MIDI adapter is a Dreamcast peripheral that connects to the serial port and allows MIDI instrument input and output for use with the Japanese-only title O-to-i-re: Dreamcast Sequencer. {{DCWiki:Stub}} 7e533a0842f0781c7ec5d52a7387ab36d371acf8 Neo Geo Pocket Color link cable 0 33 273 107 2020-01-11T00:19:15Z Unknown user 0 wikitext text/x-wiki The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported. * Bikkuriman 2000 Viva! Festival! connects to Bikkuriman 2000 Viva! Pocket Festival! * Capcom vs. SNK: Millennium Fight 2000 connects to SNK vs. Capcom: Match of the Millennium * Capcom vs. SNK 2: Millionaire Fighting 2001 connects to SNK vs. Capcom: Card Fighters 2 Expand Edition * Cool Cool Toon connects to Cool Cool Jam * The King of Fighters: Evolution connects to King of Fighters: Battle de Paradise * The King of Fighters Dream Match '99 connects to King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium {{DCWiki:Stub}} 871662d3ddaeac9434da7fb897a6baa5c822819d VS cable 0 32 274 104 2020-01-11T00:19:22Z Unknown user 0 wikitext text/x-wiki The Dreamcast VS cable is a rare, serial-based cable that connects two Dreamcast consoles together for multiplayer games. The cable was only released in Japan. There was also an aftermarket version released by Dragoncast, but this cable is also rare. Only 5 titles are compatible. * Aero Dancing F * Aero Dancing i * Cyber Troopers Virtual-On: Oratorio Tangram * F355 Challenge * Sega Tetris {{DCWiki:Stub}} 9c798f72c81286d23782752ffeaa616601af45d6 Coder's cable 0 90 275 264 2020-01-11T00:19:32Z Unknown user 0 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). {{DCWiki:Stub}} b1a40613f42367e2c186ac1f7e5e5d432ddaa7bb Serial SD card adapter 0 15 276 228 2020-01-11T00:19:42Z Unknown user 0 wikitext text/x-wiki The serial SD card adapter is a community-designed peripheral that allows software to access an SD card for reading and writing through the Dreamcast's serial connector. Files can be accessed and manipulated using [[DreamShell]]. Code and games can be executed from the SD card, but because access is limited by the slow serial connectivity, running commercial games in this way is typically slow and buggy. Gamers looking to play games via SD card should look for an [[Optical drive replacements|optical drive replacement]] instead. {{DCWiki:Stub}} f690955699c7cc05f8fe571f0d2ba08618c19f16 Indie games 0 13 277 237 2020-01-11T00:19:46Z Unknown user 0 /* Released */ wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} 59e8480ecece264c6082ff90bd6d7f726040fd9f Karaoke 0 92 278 2020-01-11T00:23:04Z Unknown user 0 Created page with "The Karaoke deck is an expansion for the Dreamcast that allows the console to be used as a karaoke machine. It connects to the [[G2 bus]] and sits below the console, doubling..." wikitext text/x-wiki The Karaoke deck is an expansion for the Dreamcast that allows the console to be used as a karaoke machine. It connects to the [[G2 bus]] and sits below the console, doubling its size vertically. It has two microphone jacks for karaoke microphones as well as volume dials. {{DCWiki:Stub}} 5e025a95c0061660aedc3c33f53d2b747fec9037 Serial interface 0 93 279 2020-01-11T00:24:05Z Unknown user 0 Created page with "The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. {{DCWiki:Stub}}" wikitext text/x-wiki The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. {{DCWiki:Stub}} d35944aee0a23046624c231ef42ab72b8ac51762 BIOS 0 78 280 238 2020-01-11T00:24:30Z Unknown user 0 wikitext text/x-wiki The Sega Dreamcast BIOS has several known revisions: * v1.004 or MPR-21068, found in Japanese consoles only * v1.01c or MPR-21871, found in PAL consoles * v1.01d or MPR-21931 or MPR-21933, found in consoles worldwide ** The [[Treamcast]] console uses a hacked version of this firmware with Chinese support. * v1.022 or MPR-23588, found in U.S. and Japanese consoles ** Consoles with this revision BIOS have [[MIL-CD]] booting disabled. {{DCWiki:Stub}} 6c8d3c377b3a4655f5c50d80b6ed659b9258ed89 DreamPi 0 18 281 196 2020-01-11T00:24:55Z Unknown user 0 wikitext text/x-wiki DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. {{DCWiki:Stub}} 3f2053a4c027bd38a174a0cbf079e86af7365a79 BIOS modification 0 12 282 39 2020-01-11T00:25:04Z Unknown user 0 wikitext text/x-wiki The Dreamcast's BIOS chip can be replaced (or a secondary chip added) to remove region checks, A/V connectivity compatibility checks, and add new features. {{DCWiki:Stub}} aed0f3d071dd25ecd6a94308242cd82284e2a890 DCDigital 0 14 283 51 2020-01-11T00:25:34Z Unknown user 0 wikitext text/x-wiki DCHDMI is a modification kit created by chriz2600 and citrus3000psi which adds native HDMI output to the Sega Dreamcast. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] {{DCWiki:Stub}} 50ebe3743efac81d955085625129f502b9ae702c Volgarr the Viking 0 94 284 2020-01-11T00:27:21Z Unknown user 0 Created page with "== Volgarr the Viking == You are Volgarr! Do you have what it takes to be the greatest Viking Barbarian Lord in the world? <br> Return to the Golden Age of arcade gaming with..." wikitext text/x-wiki == Volgarr the Viking == You are Volgarr! Do you have what it takes to be the greatest Viking Barbarian Lord in the world? <br> Return to the Golden Age of arcade gaming with all-new hardcore action experience that pulls no punches. <br> Playing as Volgarr the Viking, use your sword and spear to slaughter your foes in bloody combat. <br> Battle Gigantic bosses in every world and find secrets that lead to unknown paths. <br> Holding onto Volgarr's gear is key; his very life depends on it. https://volgarr.rkd.zone/ Website of the Dreamcast Port by Mark Hall <br> http://www.volgarrtheviking.com/ Crazy Viking Studios' site for the game fb25f5800de832a2fd6b793f85593afc4954a109 286 284 2020-01-11T00:27:36Z Unknown user 0 /* Volgarr the Viking */ wikitext text/x-wiki You are Volgarr! Do you have what it takes to be the greatest Viking Barbarian Lord in the world? <br> Return to the Golden Age of arcade gaming with all-new hardcore action experience that pulls no punches. <br> Playing as Volgarr the Viking, use your sword and spear to slaughter your foes in bloody combat. <br> Battle Gigantic bosses in every world and find secrets that lead to unknown paths. <br> Holding onto Volgarr's gear is key; his very life depends on it. https://volgarr.rkd.zone/ Website of the Dreamcast Port by Mark Hall <br> http://www.volgarrtheviking.com/ Crazy Viking Studios' site for the game f33f3be647ee576ba4bf6bd5c3df81e420a9b030 F1 fuse repair 0 95 285 2020-01-11T00:27:24Z Unknown user 0 Created page with "The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an auto..." wikitext text/x-wiki The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. {{DCWiki:Stub}} 3ff79e523dffc096936411e89a24c71425791136 Battery replacement 0 96 287 2020-01-11T00:30:49Z Unknown user 0 Created page with "The Dreamcast uses a soldered-in, rechargeable ML2032 battery to store the console's time and date settings. The battery recharges whenever the console is powered on. The batt..." wikitext text/x-wiki The Dreamcast uses a soldered-in, rechargeable ML2032 battery to store the console's time and date settings. The battery recharges whenever the console is powered on. The batteries on most all Dreamcast consoles should be dead by now, so one can desolder the original battery and replace it with a plastic battery holder so the console owner can replace the ML2032 anytime with only a screwdriver. It is recommended not to use the LIR2032 battery type as the Dreamcast does not output the voltage necessary for it to properly recharge. {{DCWiki:Stub}} fb42519ad8dc77b00cf992f26c8c6bd6dc709729 GD-ROM drive repair 0 97 288 2020-01-11T00:34:15Z Unknown user 0 Created page with "The GD-ROM drive is known to be temperamental and many of them fail easily. The drives may be brought to life by re-calibration, adjustment of the laser potentiometer, or repl..." wikitext text/x-wiki The GD-ROM drive is known to be temperamental and many of them fail easily. The drives may be brought to life by re-calibration, adjustment of the laser potentiometer, or replacement of capacitors on the GD-ROM PCB. {{DCWiki:Stub}} 881379d834887f63f2742659719a01c39a2fb75b PSU repair 0 98 289 2020-01-11T00:36:14Z Unknown user 0 Created page with "A very common problem with the Dreamcast is for the console to erratically reboot when the console has heated to a normal playing temperature. This is often caused by poor con..." wikitext text/x-wiki A very common problem with the Dreamcast is for the console to erratically reboot when the console has heated to a normal playing temperature. This is often caused by poor contact between the power supply's connection to the motherboard. Cleaning and adjusting the pins often fixes this problem. {{DCWiki:Stub}} a9f76e5f19c2fc3c23ac3cb6b6ff8d9525019e9c IDE hard drive modification 0 25 290 72 2020-01-11T00:43:57Z Unknown user 0 wikitext text/x-wiki The Dreamcast IDE hard drive modification allows one to connect an IDE hard drive (or SATA hard drive, with a proper compatible adapter) to the Dreamcast for storage of files and games. Using [[DreamShell]], one can execute games from the hard drive with great (although not perfect) compatibility and access times. {{DCWiki:Stub}} 2151460c670421caebf50418fc70059a69c3a0e0 VMU development 0 99 291 2020-01-11T00:52:38Z Unknown user 0 Created page with "Here's a great resource to get started: [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link] {{DCWiki:Stub}}" wikitext text/x-wiki Here's a great resource to get started: [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link] {{DCWiki:Stub}} 131ebc616dbdd7d1183305ad3d41451636edf215 293 291 2020-01-11T00:56:52Z Unknown user 0 wikitext text/x-wiki Here are some reference resources to get started * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 426b0152683a969c99bd3dba7b3cb4e13ed5e587 305 293 2020-01-11T01:48:47Z Unknown user 0 Added a few useful developer links. wikitext text/x-wiki Here are some reference resources to get started * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [http://evmu.elysianshadows.com/ VMU Emulator, File Manager, Debugger] * [http://https://github.com/wtetzner/waterbear VMU Assembler] * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 927dda276deb0f008ba05ec54e4e39cc76c6bdae 306 305 2020-01-11T01:49:22Z Unknown user 0 wikitext text/x-wiki Here are some reference resources to get started * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [http://evmu.elysianshadows.com/ ElysianVMU] - Emulator, File Manager, Debugger * [http://https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 8126c3c4bdfe3d1c8ff4096c9482578ccff62ddb 309 306 2020-01-11T02:06:48Z Unknown user 0 wikitext text/x-wiki Here are some reference resources to get started * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [http://evmu.elysianshadows.com/ ElysianVMU] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} f1446948ffe64d2b604df902e3f516e6519f69e6 File:VMU.pdf 6 100 292 2020-01-11T00:55:39Z Unknown user 0 Dreamcast (VMU)Visual Memory Unit Tutorial Manual Specifications Hardware Manual Programing Manual VMU-BIOS Specifications Sound Development Specifications Simulator Manual wikitext text/x-wiki == Summary == Dreamcast (VMU)Visual Memory Unit Tutorial Manual Specifications Hardware Manual Programing Manual VMU-BIOS Specifications Sound Development Specifications Simulator Manual 3a9a72cd4a2fa5c8fdcb90b6a63fc47703418619 S/PDIF 0 101 294 2020-01-11T00:59:14Z Unknown user 0 Created page with "The Dreamcast is capable of outputting digital audio in S/PDIF format (using optical or coaxial) with a hardware modification. {{DCWiki:Stub}}" wikitext text/x-wiki The Dreamcast is capable of outputting digital audio in S/PDIF format (using optical or coaxial) with a hardware modification. {{DCWiki:Stub}} b549fd8f9f69b9b9248e356124fb016c49939e11 298 294 2020-01-11T01:18:16Z Unknown user 0 wikitext text/x-wiki The Dreamcast is capable of outputting digital audio in S/PDIF format (using optical or coaxial) with a hardware modification. [https://gamesx.com/wiki/doku.php?id=av:dreamcastda reference link] {{DCWiki:Stub}} 3dbef977619b7204d51d48162449f1794065e6f7 Internal VGA 0 102 295 2020-01-11T01:01:17Z Unknown user 0 Created page with "The Dreamcast can output a VGA video signal, but this typically requires a VGA box or VGA cable accessory for the Dreamcast's A/V port. Alternatively, the Dreamcast can be mod..." wikitext text/x-wiki The Dreamcast can output a VGA video signal, but this typically requires a VGA box or VGA cable accessory for the Dreamcast's A/V port. Alternatively, the Dreamcast can be modded to finish the VGA circuit without a VGA box and a normal VGA connector can be mounted on the back of the console. {{DCWiki:Stub}} a3b4f92be4fc3d503bf580fc4666b8e7f355e62e Touchscreen 0 103 296 2020-01-11T01:03:48Z Unknown user 0 Created page with "Although never sold as an official peripheral for the Dreamcast, Sega created a serial-based touchscreen interface for the console for their [[Fish Life]] series of devices. P..." wikitext text/x-wiki Although never sold as an official peripheral for the Dreamcast, Sega created a serial-based touchscreen interface for the console for their [[Fish Life]] series of devices. Preliminary support for the touchscreen has been added to the [[Demul]] codebase. {{DCWiki:Stub}} 454d0f3edb0849610d03d29e6fffae26a6699154 DCWiki:Software 4 81 297 243 2020-01-11T01:15:00Z Unknown user 0 wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 52716f1a6602e16cb30c8d2e9dd770ec3d7dcebe Template:Autolink user 10 104 299 2020-01-11T01:20:59Z Unknown user 0 Created page with "{{#ifexist: User:{{{1}}} | [[User:{{{1}}}|{{{1}}}]] | [[{{{1}}}]] }}" wikitext text/x-wiki {{#ifexist: User:{{{1}}} | [[User:{{{1}}}|{{{1}}}]] | [[{{{1}}}]] }} 40b1a2789fbd78f24e35525cf9efee5321a66c1d Memory map 0 105 300 2020-01-11T01:25:47Z Unknown user 0 Created page with "= Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming:..." wikitext text/x-wiki = Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming: Memory Map, Marcus Comstedt</ref> When the built-in MMU is active, the mapping between logical and physical address is basically left up to the programmer (see the SH4 Hardware Manual for details), however the normal mode of operation in the Dreamcast is to have the MMU disabled, in which the mapping is fixed as described below. = Logical address format= When the MMU is disabled, the 32-bit logical addresses have the following format: {| class=wikitable ! 31 ! 30 ! 29 ! 28 ... 0 |- | P | ALT | NC | Physical address |} === Modifier Bits === In addition to the physical address, the following modifier bits are used: {|class=wikitable ! P | Privileged Access | Addresses with the P bit set can only be accessed when the CPU is running in privileged mode, that is when the MD bit in the status register is set. An exception to this is the Store Queue though. P inhibits the MMU, and enables the ALT and NC bits. If P is not set, ALT and NC are ignored. |- ! ALT | Alternate Address Space | Setting this bit gives an alternate mapping of the physical address bits. If NC is also set, the builtin CPU I/O registers are selected. If NC is not set, MMU translation is selected (if MMU is enabled) even though P is set. |- ! NC | Not Cacheable | Setting this bit circumvents the data cache, which is useful for accessing external hardware registers. |} === Modifier Bit Combinations === The following table shows the possible combinations of the modifier bits: {|class=wikitable !P !ALT !NC !Address range !Description !Area name |- |0 |X |X |0x00000000-0x7FFFFFFF (Physical address space repeats 4 times) |Address translation through MMU (if enabled). Can be accessed in both User and Privileged mode. |U0/P0 |- |1 |0 |0 |0x80000000-0x9FFFFFFF |Privileged mode only. |P1 |- |1 |0 |1 |0xA0000000-0xBFFFFFFF |Privileged mode only, no cache. |P2 |- |1 |1 |0 |0xC0000000-0xDFFFFFFF |Privileged mode only. Address translation through MMU (if enabled). |P3 |- |1 |1 |1 |0xE0000000-0xFFFFFFFF |Privileged mode only. Internal I/O register access. No cache. |P4 |} ==Physical address format== With exception of the P4 area, the different logical address areas share the same physical address space. This address space (of 29 bits) is divided into eight different areas of 64MB size each. {|class=wikitable !Physical address !Contents !Name |- |0x00000000-0x03FFFFFF |Boot ROM (2MB) Flash ROM (256K) Hardware registers |Area 0 |- |0x04000000-0x07FFFFFF |Video RAM (8MB) |Area 1 |- |0x08000000-0x0BFFFFFF | |Area2 |- |0x0C000000-0x0FFFFFFF |System RAM (16MB) |Area 3 |- |0x10000000-0x13FFFFFF |Tile accelerator command input |Area 4 |- |0x14000000-0x17FFFFFF |Expansion (modem) port |Area 5 |- |0x18000000-0x1BFFFFFF | |Area 6 |- |0x1C000000-0x1FFFFFFF |Internal I/O registers (same as P4) |Area 7 |} Accesses to Area 7 require the CPU to be running in privileged mode even if the access is through U0. ==References== <references/> ddc135decbe7b056082e5222f9b6813d4bb5d02c Template:RegionDate 10 106 301 2020-01-11T01:26:46Z Unknown user 0 Created page with "<small>{{{1}}}</small> {{{2}}}<br>" wikitext text/x-wiki <small>{{{1}}}</small> {{{2}}}<br> 0eb6f0435332b8ded0574a833277332f654ecc45 Template:Panel 10 46 302 143 2020-01-11T01:39:35Z Unknown user 0 wikitext text/x-wiki <div class="panel {{{class|}}}"> <div class="panel-heading" style="background-color: #666;color: #f8f8f8;padding: 0.25em 0.5em;border-top-left-radius: 3px;border-top-right-radius: 3px;">{{{1}}}</div> <div class="panel-body" style="background-color: #eee;padding: 0.25em 0.5em;border-top-left-radius: 3px;border-top-right-radius: 3px;">{{{2}}}</div> </div> <div style="clear: left"></div> 85e883491d3d49cb1e7262f8aac64c81fb2c9253 File:Milcd logo.png 6 107 303 2020-01-11T01:41:34Z Unknown user 0 MIL-CD official logo wikitext text/x-wiki == Summary == MIL-CD official logo 30055b23381777bc9722c5d3ca1e788143d5e6f1 MIL-CD 0 64 304 198 2020-01-11T01:43:24Z Unknown user 0 wikitext text/x-wiki [[File:Milcd_logo.png|thumb|right|Official MIL-CD logo]] '''MIL-CD''' is the name given to the Dreamcast format for loading code from a CD-ROM or CD-R. There were eight official MIL-CD releases, distributed in Japan only, all of which were audio music CDs containing extra audiovisual content when loaded in a Dreamcast console. This format was reverse engineered by the community to load homebrew code and pirated software, as well as create independent, unofficial commercial game releases. Additionally, it is now possible to make new custom Mil-CDs in the original intended format consisting of audio + video and playable on a Dreamcast. 60ba0433e4b166222534f7429a9bf3fb9491a45d Emulators on Dreamcast 0 108 307 2020-01-11T02:04:48Z Unknown user 0 Created page with "This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800..." wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) c1e4f607b36536060641da68f6a8f13951a9efa2 Template:Download 10 44 308 141 2020-01-11T02:06:01Z Unknown user 0 wikitext text/x-wiki {|cellpadding="0" cellspacing="0" class="infobox download" style="float:none;background-color: #eee; {{#if: {{{file|}}} ||display: none}}" | |- |style="padding: 10px 15px; line-height: 2em;vertical-align: middle;" | [[Media:{{{file}}}|<i class="fa fa-download fa-2x" style="padding-right: 5px"></i> Download {{#if: {{{title|}}} | {{{title}}} | {{PAGENAME}} }} ]] <span style="font-size: 10px">([[:File:{{{file}}}|info]]{{#if: {{{raw|}}} | , [[Media:{{{raw}}}|raw dump]] |}})</span> |} 30de6ce1b8418b0c3d64667166763d39ba52291b Other Dreamcast software 0 109 310 2020-01-11T02:10:54Z Unknown user 0 Created page with "* [[CBLoader]] * [[DCHakker]] * [[DemoMenu]] * [[DreamExplorer/VMUTool]] * [[DreamShell]] * [[Dream Photo Manager]] * [[Flash Internet Settings Adjuster]] * [[FlashROM Eraser]..." wikitext text/x-wiki * [[CBLoader]] * [[DCHakker]] * [[DemoMenu]] * [[DreamExplorer/VMUTool]] * [[DreamShell]] * [[Dream Photo Manager]] * [[Flash Internet Settings Adjuster]] * [[FlashROM Eraser]] * [[LinuxDC]] * [[NetBSD/Dreamcast]] * [[NTSC and PAL Enforcer]] * [[Sylverant PSO Patcher]] {{DCWiki:Stub}} adbb7ce0f11cbc7737e4e6c7d4caa205df847922 Template:Release 10 42 311 139 2020-01-11T02:12:22Z Unknown user 0 wikitext text/x-wiki <includeonly>{| cellpadding="0" cellspacing="0" class="infobox" style="margin-left:1em;float: right;background-color: #eee;" width="{{ #if: {{{boxwidth|}}} | {{{boxwidth}}} | 262 }}px" | style="text-align: center;" | {{#if: {{{noscreen|}}} | | {{imageexists | file = {{#if: {{{titlescreen|}}} | {{{titlescreen}}} | {{PAGENAME}}-title.png }} | maxwidth = 320 | caption= Title Screen | property= Has title screenshot | missingcat = Missing title screenshots }}}} |- |style="background-color: #666; color: #f8f8f8; padding: 5px 10px;text-align: -internal-center;text-align: center;font-size: 1.1em;" | {{#replace:{{PAGENAME}}|!|&#33;}} |- |style="padding: 10px; line-height: 1.5em;" | {| {{ #if: {{{date|}}} | {{!}}'''Date''' {{!}}{{!}} {{{date}}} {{!}}- | }} {{ #if: {{{version|}}} | {{!}}'''Version''' {{!}}{{!}} {{{version}}} {{!}}- | }} {{ #if: {{{builddate|}}} | {{!}}'''Build date''' {{!}}{{!}} [[Has build date::{{{builddate}}}]] [[Has sort date::{{{builddate}}}| ]] {{!}}- | [[Has sort date::1970| ]] }} {{ #if: {{{releasedby|}}} | {{!}}'''Released by''' {{!}}{{!}} {{Autolink user|{{{releasedby}}} }} [[Was released by::{{{releasedby}}}| ]] {{!}}- | }} {{ #if: {{{name|}}} | {{!}} style="padding-top: 14px" {{!}}'''Name''' {{!}} style="padding-top: 14px" {{!}} {{{name}}} {{!}}- | }} {{!}}- | }} {{ #if: {{{genre|}}} | {{!}}'''Genre''' {{!}}{{!}} {{{genre}}} {{!}}- | }} {{ #switch: {{{unreleased|}}} | yes | Yes = {{!}}'''Release&nbsp;date''' {{!}}{{!}} Unreleased |{{!}}'''Release&nbsp;date''' {{!}}{{!}} {{{release_date}}} {{!}}-}} |} |}</includeonly> <noinclude> = Example How to Use = {{Release |Page name=nuQuake |titlescreen=nuQuake-1.gif |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake_title.png|Title screen </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. </noinclude> f0924bfbb67990847a72364a44b7d205f25ff135 NuQuake 0 110 312 2020-01-11T02:13:37Z Unknown user 0 Created page with "{{Release |Page name=nuQuake |titlescreen=nuquake-1.png |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {..." wikitext text/x-wiki {{Release |Page name=nuQuake |titlescreen=nuquake-1.png |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake_title.png|Title screen </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. ef58e93f86e4d894dde4558f13d974d5c806e5a5 315 312 2020-01-11T02:19:06Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=nuQuake |titlescreen=nuquake-1.png |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake-1.png|Title screen nuquake_ingame.png|First Scene Ingame </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. 0a6289c17d07281941c4e10a746b99f9db6902f7 File:Nuquake-1.png 6 111 313 2020-01-11T02:17:07Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Nuquake ingame.png 6 112 314 2020-01-11T02:18:14Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Template:Imageexists 10 43 316 140 2020-01-11T02:25:35Z Unknown user 0 wikitext text/x-wiki <includeonly> {{#ifexist: File:{{{file}}} |{{#if: {{{property|}}} | [[{{{property|}}}::File:{{{file}}}|]] |}}[[File:{{{file}}}{{ #if: {{{maxwidth|}}} | {{#ifexpr: {{#mediawidth:File:{{{file}}}}}>={{{maxwidth}}} | {{!}}{{{maxwidth}}}px |}}|}}{{ #if: {{{link|}}} | {{!}}link={{{link}}} |}}{{ #if: {{{caption|}}} | {{!}}{{{caption}}} | }}]] | [[File:NoImage.png|link={{fullurl:Special:Upload|wpDestFile={{{file}}}}}|Click to upload a new image...]] {{#if: {{{missingcat|}}} | [[Category:{{{missingcat}}}|{{PAGENAME}}]] | }}<span style="display: none;">[[Media:{{{file}}}|Dummy link]]</span>}} </includeonly> <noinclude><span style="display: none;">Lovingly lifted from TCRF, somewhat edited.</span></noinclude> 700155f21d039e400e8fa26d21399c4ce4b30a00 Maple bus 0 113 317 2020-01-11T02:28:34Z Unknown user 0 Created page with "The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. {{DCWiki:Stub}}" wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. {{DCWiki:Stub}} 7a868c355e5e25318d1d719ddab97183acb9836c Template:Imageexists 10 43 318 316 2020-01-11T02:35:31Z Unknown user 0 wikitext text/x-wiki <includeonly>{{#ifexist: File:{{{file}}} |{{#if: {{{property|}}} | [[{{{property|}}}::File:{{{file}}}|]] |}}[[File:{{{file}}}{{ #if: {{{maxwidth|}}} | {{!}}{{{maxwidth}}}px |}}{{ #if: {{{link|}}} | {{!}}link={{{link}}} |}}{{ #if: {{{caption|}}} | {{!}}{{{caption}}} | }}]] | [[File:NoImage.png|link={{fullurl:Special:Upload|wpDestFile={{{file}}}}}|Click to upload a new image...]] <span style="display: none;">[[Media:{{{file}}}|Dummy link]]</span>}}</includeonly> <noinclude> {{imageexists | file = {{#if: {{{titlescreen|nuquake-1.png}}} | nuquake-1.png | {{PAGENAME}}-title.png }} | maxwidth = 320 | caption= Title Screen }} <span style="display: none;">Lovingly lifted from TCRF, somewhat edited.</span></noinclude> c3ae9599416de50fcaee11205ef34a1aaa506edb 319 318 2020-01-11T02:37:13Z Unknown user 0 wikitext text/x-wiki <includeonly>{{#ifexist: File:{{{file}}} | [[File:{{{file}}}{{ #if: {{{maxwidth|}}} | {{!}}{{{maxwidth}}}px |}}{{ #if: {{{link|}}} | {{!}}link={{{link}}} |}}{{ #if: {{{caption|}}} | {{!}}{{{caption}}} | }}]] | [[File:NoImage.png|link={{fullurl:Special:Upload|wpDestFile={{{file}}}}}|Click to upload a new image...]] <span style="display: none;">[[Media:{{{file}}}|Dummy link]]</span>}}</includeonly> <noinclude> {{imageexists | file = {{#if: {{{titlescreen|nuquake-1.png}}} | nuquake-1.png | {{PAGENAME}}-title.png }} | maxwidth = 320 | caption= Title Screen }} <span style="display: none;">Lovingly lifted from TCRF, somewhat edited.</span></noinclude> 9fa1af762b4d8bb47671d6178f0a0b15bd8b1e9c Template:Release 10 42 320 311 2020-01-11T02:37:45Z Unknown user 0 wikitext text/x-wiki <includeonly>{| cellpadding="0" cellspacing="0" class="infobox" style="margin-left:1em;float: right;background-color: #eee;" width="{{ #if: {{{boxwidth|}}} | {{{boxwidth}}} | 262 }}px" | style="text-align: center;" | {{#if: {{{noscreen|}}} | | {{imageexists | file = {{#if: {{{titlescreen|}}} | {{{titlescreen}}} | {{PAGENAME}}-title.png }} | maxwidth = 320 | caption= Title Screen }}}} |- |style="background-color: #666; color: #f8f8f8; padding: 5px 10px;text-align: -internal-center;text-align: center;font-size: 1.1em;" | {{#replace:{{PAGENAME}}|!|&#33;}} |- |style="padding: 10px; line-height: 1.5em;" | {| {{ #if: {{{date|}}} | {{!}}'''Date''' {{!}}{{!}} {{{date}}} {{!}}- | }} {{ #if: {{{version|}}} | {{!}}'''Version''' {{!}}{{!}} {{{version}}} {{!}}- | }} {{ #if: {{{builddate|}}} | {{!}}'''Build date''' {{!}}{{!}} [[Has build date::{{{builddate}}}]] [[Has sort date::{{{builddate}}}| ]] {{!}}- | [[Has sort date::1970| ]] }} {{ #if: {{{releasedby|}}} | {{!}}'''Released by''' {{!}}{{!}} {{Autolink user|{{{releasedby}}} }} [[Was released by::{{{releasedby}}}| ]] {{!}}- | }} {{ #if: {{{name|}}} | {{!}} style="padding-top: 14px" {{!}}'''Name''' {{!}} style="padding-top: 14px" {{!}} {{{name}}} {{!}}- | }} {{!}}- | }} {{ #if: {{{genre|}}} | {{!}}'''Genre''' {{!}}{{!}} {{{genre}}} {{!}}- | }} {{ #switch: {{{unreleased|}}} | yes | Yes = {{!}}'''Release&nbsp;date''' {{!}}{{!}} Unreleased |{{!}}'''Release&nbsp;date''' {{!}}{{!}} {{{release_date}}} {{!}}-}} |} |}</includeonly> <noinclude> = Example How to Use = {{Release |Page name=nuQuake |titlescreen=nuQuake-1.gif |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake_title.png|Title screen </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. </noinclude> 60b243082d2548b55003eba97ee3e601f54daba2 322 320 2020-01-11T02:39:57Z Unknown user 0 wikitext text/x-wiki <includeonly>{| cellpadding="0" cellspacing="0" class="infobox" style="margin-left:1em;float: right;background-color: #eee;" width="{{ #if: {{{boxwidth|}}} | {{{boxwidth}}} | 262 }}px" | style="text-align: center;" | {{#if: {{{noscreen|}}} | | {{imageexists | file = {{#if: {{{titlescreen|}}} | {{{titlescreen}}} | {{PAGENAME}}-title.png }} | maxwidth = 320 | caption= Title Screen }}}} |- |style="background-color: #666; color: #f8f8f8; padding: 5px 10px;text-align: -internal-center;text-align: center;font-size: 1.1em;" | {{#replace:{{PAGENAME}}|!|&#33;}} |- |style="padding: 10px; line-height: 1.5em;" | {| {{ #if: {{{date|}}} | {{!}}'''Date''' {{!}}{{!}} {{{date}}} {{!}}- | }} {{ #if: {{{version|}}} | {{!}}'''Version''' {{!}}{{!}} {{{version}}} {{!}}- | }} {{ #if: {{{builddate|}}} | {{!}}'''Build date''' {{!}}{{!}} [[Has build date::{{{builddate}}}]] [[Has sort date::{{{builddate}}}| ]] {{!}}- | [[Has sort date::1970| ]] }} {{ #if: {{{releasedby|}}} | {{!}}'''Released by''' {{!}}{{!}} {{Autolink user|{{{releasedby}}} }} [[Was released by::{{{releasedby}}}| ]] {{!}}- | }} {{ #if: {{{name|}}} | {{!}} style="padding-top: 14px" {{!}}'''Name''' {{!}} style="padding-top: 14px" {{!}} {{{name}}} {{!}}- | }} {{!}}- | }} {{ #if: {{{genre|}}} | {{!}}'''Genre''' {{!}}{{!}} {{{genre}}} {{!}}- | }} {{ #switch: {{{unreleased|}}} | yes | Yes = {{!}}'''Release&nbsp;date''' {{!}}{{!}} Unreleased |{{!}}'''Release&nbsp;date''' {{!}}{{!}} {{{release_date}}} {{!}}-}} |} |}</includeonly> <noinclude> = Example How to Use = {{Release |Page name=nuQuake |titlescreen=nuquake-1.png |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake-1.png|Title screen nuquake_ingame.png|First Scene Ingame </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. __NOTOC__ </noinclude> 43e9e704162cb2c4dc57dfea909a9efa145d33c7 NuQuake 0 110 321 315 2020-01-11T02:39:35Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=nuQuake |titlescreen=nuquake-1.png |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake-1.png|Title screen nuquake_ingame.png|First Scene Ingame </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. __NOTOC__ 0c9e48b8349e321b93b47ad26f28461050cacbd9 Engine & Library 0 27 323 82 2020-01-11T02:41:07Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake]() - Quake engine by Ian Micheal * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) e93f722dc32b4124400f9daaab5d045bd9f629e9 NeoIP 0 114 324 2020-01-11T02:46:58Z Unknown user 0 Created page with "{{Release |Page name=neoIP |titlescreen=neoip-1.png |status=Released |releasedby=HaydenKow |name=neoIP |genre=Tool, Utility |release_date= |unreleased=No }} {{Download |file=..." wikitext text/x-wiki {{Release |Page name=neoIP |titlescreen=neoip-1.png |status=Released |releasedby=HaydenKow |name=neoIP |genre=Tool, Utility |release_date= |unreleased=No }} {{Download |file= }} == Description == '''Original Release Announcement''' it started as ip_cracktro which was written as a framework for making intros and cracktros without tampering with 1ST_READ.BINS and such. The project has grown up a little and now we have neoIP a more stable, more feature-filled, wholly new way of making an [[IP.BIN]] == Screenshots == <gallery mode=nolines heights=168 widths=240> neoip-1.png|Title screen </gallery> == Technical == * Open Source Verstile [[IP.BIN]] == Thanks == Thanks to megavolt85, AG. __NOTOC__ f46b51fae63067665b1d395730d766212403f398 326 324 2020-01-11T02:49:37Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=neoIP |titlescreen=neoip-1.png |status=Released |releasedby=HaydenKow |name=neoIP |genre=Tool, Utility |release_date= |unreleased=No }} {{Download |file= }} == Description == '''Original Release Announcement''' it started as ip_cracktro which was written as a framework for making intros and cracktros without tampering with 1ST_READ.BINS and such. The project has grown up a little and now we have neoIP a more stable, more feature-filled, wholly new way of making an [[IP.BIN]] == Screenshots == <gallery mode=nolines heights=168 widths=240> neoip-1.png|Title screen </gallery> == Technical == * Open Source * Configurable, and extensible [[IP.BIN]] * Basic binary patching * Boots KATANA, WINCE, and Homebrew binaries, scrambled or not == Source == [https://github.com/mrneo240/neoIP] == Thanks == Thanks to megavolt85, AG. __NOTOC__ 7e884729736e881ebe4ec7373650b37bf111ea36 327 326 2020-01-11T02:49:59Z Unknown user 0 /* Source */ wikitext text/x-wiki {{Release |Page name=neoIP |titlescreen=neoip-1.png |status=Released |releasedby=HaydenKow |name=neoIP |genre=Tool, Utility |release_date= |unreleased=No }} {{Download |file= }} == Description == '''Original Release Announcement''' it started as ip_cracktro which was written as a framework for making intros and cracktros without tampering with 1ST_READ.BINS and such. The project has grown up a little and now we have neoIP a more stable, more feature-filled, wholly new way of making an [[IP.BIN]] == Screenshots == <gallery mode=nolines heights=168 widths=240> neoip-1.png|Title screen </gallery> == Technical == * Open Source * Configurable, and extensible [[IP.BIN]] * Basic binary patching * Boots KATANA, WINCE, and Homebrew binaries, scrambled or not == Source == [https://github.com/mrneo240/neoIP https://github.com/mrneo240/neoIP] == Thanks == Thanks to megavolt85, AG. __NOTOC__ 1a7b91b14a3dfacf75916b45dba03dde72bbb81a 329 327 2020-01-11T02:51:04Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=neoIP |titlescreen=neoip-1.png |status=Released |releasedby=HaydenKow |name=neoIP |genre=Tool, Utility |release_date= Feb 21, 2018 |unreleased=No }} {{Download |file= }} == Description == '''Original Release Announcement''' it started as ip_cracktro which was written as a framework for making intros and cracktros without tampering with 1ST_READ.BINS and such. The project has grown up a little and now we have neoIP a more stable, more feature-filled, wholly new way of making an [[IP.BIN]] == Screenshots == <gallery mode=nolines heights=168 widths=240> neoip-1.png|Title screen </gallery> == Technical == * Open Source * Configurable, and extensible [[IP.BIN]] * Basic binary patching * Boots KATANA, WINCE, and Homebrew binaries, scrambled or not == Source == [https://github.com/mrneo240/neoIP https://github.com/mrneo240/neoIP] == Thanks == Thanks to megavolt85, AG. __NOTOC__ 767c8e29c093e24a9e718e9b013c49e729456735 File:Neoip-1.png 6 115 325 2020-01-11T02:47:19Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 IP.BIN 0 35 328 203 2020-01-11T02:50:10Z Unknown user 0 wikitext text/x-wiki The Dreamcast bootsector (commonly named '''IP.BIN''') is placed on a [[GD-ROM]] or a [[MIL-CD]] in the first 16 sectors of the data track from which the Dreamcast is booting. It contains information about the software on the disc, including [[region protection]], as well as the code that displays the Sega copyright screen and prepares the system for the launch of a game title. Originally the bootsector was lifted from Dreamcast games to boot homebrew software, but technically using this copyrighted code was illegal in some jurisdictions. Homebrew coder [[LiENUS]] originally [[LiENUS's IP.BIN|rewrote the IP.BIN file]], replacing as much as possible with free code. The only code that remains in this homebrew IP.BIN is Sega's copyright screen code, which is required to be unmodified in order for the disc to boot (the system checks it against a copy of the code held within the BIOS ROM). It is believed by some that using this last bit of code is legal due to the legal precedent set by ''[http://digital-law-online.info/cases/24PQ2D1561.htm Sega v. Accolade]''. New, additional functionality has been added to the IP.BIN in the [[neoIP]] replacement IP.BIN project. It is currently able to load homebrew and official Katana or Windows CE binaries from either [[GD-ROM]] or [[CD-ROM]]. == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an [[MR Image]] * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * A custom [[MR Image]] can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== This is Generally where all the base setup code is kept so our binary has a known, and clean execution environment in which it starts. In [[Warez]] releases this is the area that is responsible for a very sneaky trick. The [[1ST_READ.BIN]] binary is kept as is on the disc, but then when scramble loaded by the bios (See [[Dreamcast_Boot_Process]] for further)) it will be unusable, so code was written to unscramble, the now ruined binary, in-place. The second part of this trick also reinitializes the [[GD-ROM]] drive and passes the [[HOLLY]] bios check so that the game may access the data on the disc and execute normally. ==References== <references/> 45c1d11fcd571f1b1cf1a028042805acd9bd4171 File:Milcd logo.png 6 107 330 303 2020-01-11T02:56:46Z Unknown user 0 Neo uploaded a new version of [[File:Milcd logo.png]] wikitext text/x-wiki == Summary == MIL-CD official logo 30055b23381777bc9722c5d3ca1e788143d5e6f1 User:GyroVorbis 2 116 331 2020-01-11T03:03:21Z Unknown user 0 Created page with "Lead developer of Elysian Shadows, ESTk, and ElysianVMU, widely hated for being late on Kickstarter, but THE PROJECT IS HIS LIFE, AND HE'S WORKING ON IT and fully intends to m..." wikitext text/x-wiki Lead developer of Elysian Shadows, ESTk, and ElysianVMU, widely hated for being late on Kickstarter, but THE PROJECT IS HIS LIFE, AND HE'S WORKING ON IT and fully intends to make it up to all of you. :) 283f338f938f5008e15bd7026822d13dd66ba9a0 332 331 2020-01-11T03:03:34Z Unknown user 0 wikitext text/x-wiki Infamous lead developer of Elysian Shadows, ESTk, and ElysianVMU, widely hated for being late on Kickstarter, but THE PROJECT IS HIS LIFE, AND HE'S WORKING ON IT and fully intends to make it up to all of you. :) 259e90f0379956b4df3fc331be7ad15b0cb1bb55 Region change 0 117 333 2020-01-11T03:07:10Z Unknown user 0 Created page with "The region of a Dreamcast console is set in a read-only portion of the Dreamcast's flash ROM. A console's region can therefore be changed by performing a temporary modificatio..." wikitext text/x-wiki The region of a Dreamcast console is set in a read-only portion of the Dreamcast's flash ROM. A console's region can therefore be changed by performing a temporary modification to enable write access to that section of the Flash ROM and modifying the region setting. After the region is changed, it is strongly recommended to undo the write access modification, as software can accidentally overwrite the region information, bricking the Dreamcast. {{DCWiki:Stub}} 4c84d8a4290db67c2b79a330ef7fcce574eab38b VMU emulators 0 118 334 2020-01-11T03:14:08Z Unknown user 0 Basic VMU Emulator Page wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features 19ee1d7facaff2b4dba555ccb0999203ba4c7962 342 334 2020-01-11T03:33:47Z Unknown user 0 Added feature support list and details wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * * Status : Active, Features and new platform support added regularly * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) 5d041058e03b4c21bf9d0327c451dabbe17a1fad 347 342 2020-01-11T03:38:40Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive 12fd897abe149ef47f8cec9658ce786ac024329e 348 347 2020-01-11T03:40:18Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive b6063b0bfe5a0cc919501cb7f468310fb2e046fc 349 348 2020-01-11T03:41:22Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive 9c32183c48d88ad39e40cf8fbacd6e284dd860fb 355 349 2020-01-11T03:45:47Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive * Compatibility: Good 267a98bd657a88d63c95a11a0bacf073d3453483 357 355 2020-01-11T03:47:12Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive * Compatibility: Good 70975719f2cd517025c242797f66254c1e3493ce 358 357 2020-01-11T03:47:39Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active, Features and new platform support added regularly * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive * Compatibility: Good 1c87058553addfbee4f06b5870910a2ffdd8908c 359 358 2020-01-11T03:47:57Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive * Compatibility: Good e419388440c33b86a696f4cadffdfaffe4b9c12e 360 359 2020-01-11T03:48:18Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI *** Flash Images: .DCM, .VMU *** Other: .BIN (Bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive * Compatibility: Good 90f5f0807c094dda1cba6979742fb33def2658ae 361 360 2020-01-11T03:49:20Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developed by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI *** Flash Images: .DCM, .VMU *** Other: .BIN (Bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between File Formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developed by : Marcus Comstedt * Status : Inactive * Compatibility: Good 0704265fb5aefbd58d92e2936ead716bfa77d47b 364 361 2020-01-11T03:52:39Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developer by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows ## VeMUlator PRO * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android 1691f14b12b771cafca345e17e8dd07060468dea 365 364 2020-01-11T03:52:58Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com](https://evmu.elysianshadows.com) * Developer by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows ## VeMUlator PRO * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android dfaccbe692a7f507f4f4ae3c8d21f33607f6c9c0 366 365 2020-01-11T03:53:15Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. ## ElysianVMU ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) ## SoftVMS * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows ## VeMUlator PRO * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android 6e31928df07ce11ad78876374586673efd418491 File:Spritesheet tutorial demo sprite.gif 6 119 335 2020-01-11T03:24:49Z Unknown user 0 Originally uploaded by Bogglez Demonstrates the 16 bit precision problem for the texture coordinates when using sprite mode wikitext text/x-wiki == Summary == Originally uploaded by Bogglez Demonstrates the 16 bit precision problem for the texture coordinates when using sprite mode b943883d92d995830cb0cc444dd46bc8668f96af File:Spritesheet tutorial.gif 6 120 336 2020-01-11T03:27:23Z Unknown user 0 Originally uploaded by bogglez wikitext text/x-wiki == Summary == Originally uploaded by bogglez 0c267add49caf770e028596fee0966c64e48d55a File:Spritesheet tutorial texturepacker.png 6 121 337 2020-01-11T03:28:54Z Unknown user 0 Visual explanation of TexturePacker wikitext text/x-wiki == Summary == Visual explanation of TexturePacker 4d47fc5e84ca87952ca0d0db9bb44291ddd8f6b5 341 337 2020-01-11T03:31:21Z Unknown user 0 /* Summary */ wikitext text/x-wiki == Summary == Originally uploaded by bogglez Visual explanation of TexturePacker d27868c1b0bb7a47d78798baf8f1ddd379e444d0 File:Kos spritesheet tutorial.zip 6 122 338 2020-01-11T03:30:25Z Unknown user 0 Code and art assets for the spritesheet pvr tutorial wikitext text/x-wiki == Summary == Code and art assets for the spritesheet pvr tutorial 006aaba860a3a13d85b8312a23447968926e9038 339 338 2020-01-11T03:30:40Z Unknown user 0 /* Summary */ wikitext text/x-wiki == Summary == Originally uploaded by bogglez Code and art assets for the spritesheet pvr tutorial 62d574de0e3ab169f894a9202675cba23c2b34b0 A/V connectivity 0 8 340 266 2020-01-11T03:31:08Z Unknown user 0 wikitext text/x-wiki The Dreamcast natively supports RF video, composite video, S-video, 15KHz RGB video ("RGB SCART"), and 31KHZ RGBHV ("VGA") output. The RGB mode and VGA mode do not work for all official game titles. See [[Video mode compatibility list|the compatibility list]] for more details. Aftermarket cables containing circuits with YPbPr conversion hardware can be purchased or created. The Dreamcast can also be [[DCHDMI|modified to support HDMI output]]. {| class="wikitable" |+A/V connector pinout |- ! Pin ! Description |- |1 |Ground |- |2 |Audio (right channel) |- |3 |Audio (left channel) |- |4 | +12V |- |5 | +5V |- |6 |31KHz (grounded) or 15KHz (floating) selection |- |7 |RGB (grounded) or composite/s-video (floating) selection |- |8 |Vertical sync (in VGA mode) |- |9 |Horizontal sync (in VGA mode) |- |10 |Composite sync |- |11 |Chrominance |- |12 |Luminance |- |13 |Composite video |- |14 |Blue |- |15 |Green |- |16 |Red |} {{DCWiki:Stub}} 71d6f15190b4e8700514e0146fe82f3d2730d3ca 344 340 2020-01-11T03:35:28Z Unknown user 0 wikitext text/x-wiki The Dreamcast natively supports RF video, composite video, S-video, 15KHz RGB video ("RGB SCART"), and 31KHZ RGBHV ("VGA") output. The RGB mode and VGA mode do not work for all official game titles. See [[Video mode compatibility list|the compatibility list]] for more details. Aftermarket cables containing circuits with YPbPr conversion hardware can be purchased or created. The Dreamcast can also be [[DCHDMI|modified to support HDMI output]]. {| class="wikitable" |+A/V connector pinout |- ! Pin ! Description |- |1 |Ground |- |2 |Audio (right channel) |- |3 |Audio (left channel) |- |4 | +12V |- |5 | +5V |- |6 |31KHz (grounded) or 15KHz (floating) selection |- |7 |RGB (grounded) or composite/s-video (floating) selection |- |8 |Vertical sync (only available in RGB or VGA mode) |- |9 |Horizontal sync (only available in RGB or VGA mode) |- |10 |Composite sync (only available in RGB mode, but not VGA) |- |11 |Chrominance (only available in composite/s-video mode) |- |12 |Luminance (only available in composite/s-video mode) |- |13 |Composite video (only available in composite/s-video mode) |- |14 |Blue (only available in RGB or VGA mode) |- |15 |Green (only available in RGB or VGA mode) |- |16 |Red (only available in RGB or VGA mode) |} {{DCWiki:Stub}} 734c7745110d3dcec56a1610c0b98d1303b45602 PVR Spritesheets 0 123 343 2020-01-11T03:33:59Z Unknown user 0 Created page with "= About this tutorial = In this tutorial you will learn: * Generating a spritesheet from a directory full of single images automatically. * Converting the spritesheet into a P..." wikitext text/x-wiki = About this tutorial = In this tutorial you will learn: * Generating a spritesheet from a directory full of single images automatically. * Converting the spritesheet into a PVR paletted texture automatically. * Loading the spritesheet into the PVR for drawing. * Setting up the palette for drawing. * Drawing a user interface (with a dynamic health bar). * Drawing animated characters. * Using the PVR's sprite drawing mode (instead of polygons) This will be the end result: [[File:Spritesheet_tutorial.gif]] = Required software = Before you can get started, you will need to install two tools. == TexturePacker == The first tool you need is [https://www.codeandweb.com/texturepacker/download TexturePacker]. It packs single images together into one big spritesheet, so you don't need to do this manually. We will make it do it for us using Make. TexturePacker has some Pro features, but this tutorial limits itself to its free features. This image should give you an idea about this tools's usefulness: [[File:Spritesheet_tutorial_texturepacker.png]] It will also create text files of the following format: mage_combat6, 244, 103, 122, 103, 0, 0, 0, 0 mage_combat7, 366, 103, 122, 103, 0, 0, 0, 0 mage_idle0, 0, 206, 79, 93, 0, 0, 0, 0 mage_idle1, 79, 206, 79, 94, 0, 0, 0, 0 mage_idle2, 158, 206, 82, 94, 0, 0, 0, 0 mage_idle3, 240, 206, 85, 94, 0, 0, 0, 0 The example code will parse this information to find out where each sprite within the spritesheet is. == texconv == The next tool you need is [https://github.com/tvspelsfreak/texconv texconv] by tvspelsfreak. ''texconv'' is an alternative to KOS' ''vqenc'' for converting images such as PNG into texture formats supported by the Dreamcast's PVR graphics chip. It doesn't create KMG files, instead it creates its own DTEX format, but provides other nice features. For this tutorial paletted textures are essential. Another feature that is used is its preview feature. It will basically convert the converted texture back to PNG so you can check the quality of the conversion. texconv has a dependency on Qt5, so install that first. On Debian-based systems this will get you running: sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make You can then use ''./texconv''. I suggest you put it somewhere in your ''PATH'' for convenient global access. texconv offers the following options (options used in this tutorial are marked as '''bold'''): Usage: ./texconv [options] Texture formats: BUMPMAP PAL4BPP ARGB4444 YUV422 ARGB1555 RGB565 '''PAL8BPP''' Options: -h, --help Displays this help. '''-i, --in <filename> Input file(s). (REQUIRED)''' '''-o, --out <filename> Output file. (REQUIRED)''' '''-f, --format <format> Texture format. (REQUIRED)''' -m, --mipmap Generate/allow mipmaps. -c, --compress Output a compressed texture. -s, --stride Output a stride texture. '''-p, --preview <filename> Generate a texture preview.''' -v, --verbose Extra printouts. -n, --nearest Use nearest-neighbor filtering for scaling mipmaps. -b, --bilinear Use bilinear filtering for scaling mipmaps. --vqcodeusage <filename> Output an image that visualizes compression code usage. = Downloading and running the example code = After installing the required software, you can download [[:File:Kos spritesheet tutorial.zip|the example source code for this tutorial]]. Unzip the archive and open the directory ''kos_spritesheet_tutorial''. You will find the following directory and file structure: * ''assets'': Raw art assets that will be turned into spritesheets and converted to Dreamcast PVR textures. * ''build'': Contains temporary files. For example ''build/ui_sheet.png'' will contain all art assets from ''assets/spritesheets/ui/*''. * ''main.c'': Loading, parsing and drawing code. * ''Makefile'': Build system. Also calls ''TexturePacker'' and ''texconv'' to create the spritesheets automatically upong changing anything. * ''readme.txt'': License for the used artwork. * ''romdisk'': Contains the files that will be available at runtime of the game. After typing ''make'', you should get the following output: kos-cc -std=c11 -c main.c -o main.o Generating spritesheet build/stage1_actors_sheet.png from assets/spritesheets/stage1_actors TexturePacker --sheet build/stage1_actors_sheet.png \ --format gideros --data romdisk/stage1_actors_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ assets/spritesheets/stage1_actors Resulting sprite sheet is 512x1024 Writing sprite sheet to build/stage1_actors_sheet.png Writing romdisk/stage1_actors_sheet.txt Converting romdisk/stage1_actors_sheet.dtex < build/stage1_actors_sheet.png texconv -i build/stage1_actors_sheet.png -o romdisk/stage1_actors_sheet.dtex -f PAL8BPP -p build/stage1_actors_preview.png Generating spritesheet build/ui_sheet.png from assets/spritesheets/ui TexturePacker --sheet build/ui_sheet.png \ --format gideros --data romdisk/ui_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ assets/spritesheets/ui Resulting sprite sheet is 512x128 Writing sprite sheet to build/ui_sheet.png Writing romdisk/ui_sheet.txt Converting romdisk/ui_sheet.dtex < build/ui_sheet.png texconv -i build/ui_sheet.png -o romdisk/ui_sheet.dtex -f PAL8BPP -p build/ui_preview.png /opt/toolchains/dc/kos/utils/genromfs/genromfs -f romdisk.img -d romdisk -v 0 rom 56ef0c99 [0xffffffff, 0xffffffff] 37777777777, sz 0, at 0x0 1 . [0x802 , 0x566411 ] 0040755, sz 0, at 0x20 1 .. [0x802 , 0x56639f ] 0040755, sz 0, at 0x40 [link to 0x20 ] 1 ui_sheet.dtex.pal [0x802 , 0x5654fa ] 0100644, sz 1032, at 0x60 1 ui_sheet.txt [0x802 , 0x5654f7 ] 0100644, sz 392, at 0x4a0 1 stage1_actors_sheet.dtex [0x802 , 0x5654f3 ] 0100644, sz 524304, at 0x650 1 stage1_actors_sheet.dtex.pal [0x802 , 0x5654f4 ] 0100644, sz 104, at 0x80690 1 stage1_actors_sheet.txt [0x802 , 0x5654f2 ] 0100644, sz 1818, at 0x80730 1 ui_sheet.dtex [0x802 , 0x5654f8 ] 0100644, sz 65552, at 0x80e80 /opt/toolchains/dc/kos/utils/bin2o/bin2o romdisk.img romdisk romdisk.o kos-cc -o spritesheet.elf main.o romdisk.o -lkmg -lkosutils -lm The executable will be called ''spritesheet.elf'' and can be run in an emulator or on your Dreamcast. = Explanation = The Makefile and main.c are heavily commented, so I will only refer to the most important bits here. == Makefile == If any of these rules confuse you, compare them to the output of the ''make'' command above and things should become clear. The Makefile target spritesheet.elf (the executable of the game) depends on romdisk.o, which depends on romdisk.img. All the converted spritesheets, their palettes, and the sprite geometry info will be stored in this romdisk, therefore romdisk.img must depend on those files. We don't care about the raw art assets, however, since they're not used at runtime. To achieve this in Make, the name of all spritesheets needs to be generated first, i.e. ''assets/spritesheets/foo/*.png assets/spritesheets/bar/*.png'' needs to turn into ''foo bar'' SPRITESHEET_NAMES := $(notdir $(wildcard assets/spritesheets/*)) Now ''romdisk.img'' should depend on ''romdisk/foo_sheet.dtex'' and ''romdisk/bar_sheet.dtex''. But ''texconv'' will save the palette file separately, so we add ''romdisk/foo_sheet.dtex.pal'' etc. SPRITESHEET_RESULT_FILES := $(patsubst %,romdisk/%_sheet.dtex,$(SPRITESHEET_NAMES)) romdisk.img: $(SPRITESHEET_RESULT_FILES) $(addsuffix .pal,$(SPRITESHEET_RESULT_FILES)) $(KOS_GENROMFS) -f romdisk.img -d romdisk -v Next Make needs to know how to generate the dtex and dtex.pal files from the corresponding PNG using ''texconv''. romdisk/%_sheet.dtex romdisk/%_sheet.dtex.pal: build/%_sheet.png $(info Converting $@ < $<) texconv -i $< -o $@ -f PAL8BPP -p build/$*_preview.png This rule requires that the sprites have been assembled as ''build/foo_sheet.png'' before (using TexturePacker), so that file becomes a dependency. Notice how the texture format is set to PAL8BPP, allowing for 256 different colors in the palette. PAL4BPP is also a possibility. texconv assumes 32 bit colors in the palette. It implicitly creates the ''.dtex.pal'' file. Also take a look at the ''build/foo_preview.png'' file to see whether you suffered quality loss during the conversion. This will happen if your input image has more than 256 colors in this case. Lastly TexturePacker is called to turn all images in the directory ''assets/spritesheets/foo/'' into ''build/foo_sheet.png'' and generate ''romdisk/foo_sheet.txt'' with the sprite geometry information. The txt file is stored in ''romdisk/'' because we will parse it during runtime in order to draw the sprites. ''build/foo_sheet.png'' is just the temporary file to create the Dreamcast PVR texture ''romdisk/foo_sheet.dtex'' (and ''.pal''). TexturePacker is instructed to create power-of-two textures (e.g. 64x256) of maximum dimensions 1024x1024, because of the PVR graphics chip's limitations. The options in the last line are necessary to disable pro-version features (otherwise TexturePacker will turn some sprites red). build/%_sheet.png: assets/spritesheets/% $(info Generating spritesheet $@ from $^) TexturePacker --sheet $@ \ --format gideros --data romdisk/$*_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ $^ == The code == I'll explain the code top-down, to give you a high level view. So assume that the mentioned helper functions have already been written, they will be explained later. === The main loop === The main loop is very basic: struct spritesheet stage1_actors_sheet, ui_sheet; int main(int argc, char *argv[]) { int result = 0; if(init()) { puts("Cannot init"); result = 1; goto cleanup; } for(;;) { draw(); } cleanup: spritesheet_free(&stage1_actors_sheet); spritesheet_free(&ui_sheet); return result; } Two spritesheets are loaded within init() as global variables. Then draw() will draw some sprites on the screen repeatedly. In the end some clean-up code is called (here only if init() fails). === The drawing routine === This is the draw() function. First it needs to wait for the PVR graphics chip to be ready for drawing: static void draw() { pvr_wait_ready(); /* Await v-blank */ pvr_scene_begin(); Next, the PVR is told to expect a punchthru polygon list. This will allow you to send geometry that can have translucency per pixel (visible or not, not half, unlike transparency). If you want to send opaque or transparent polygons too, you need to do that before this code. This function implicitly closes the preceding polygon lists for the duration of this frame. pvr_list_begin(PVR_LIST_PT_POLY); Now we set up the palettes for this frame. We tell the PVR chip what colors the textures refer to (try mixing them up for fun!). Here, draw() uses my helper function setup_palette(): void setup_palette(uint32_t const * colors, uint16_t count, uint8_t palette_number); // in draw() uint8_t const ui_palette_number = 0; uint8_t const stage1_actors_palette_number = 1; setup_palette(ui_sheet.palette, ui_sheet.color_count, ui_palette_number); setup_palette(stage1_actors_sheet.palette, stage1_actors_sheet.color_count, stage1_actors_palette_number); Now the actual sprite drawing happens. We draw a little user interface and some animated characters using my helper function draw_sprite(): void draw_sprite(struct spritesheet const * const sheet, char const * const name, float x, float y, uint8_t palette_number); The arguments are * a spritesheet struct with parsed information, * the name of the sprite inside of it that should be drawn (e.g. ''healthbar_left'' in ''romdisk/ui_sheet.txt'') * x, y coordinates on screen (y goes downwards) * The number of the palette to use. Palettes on the Dreamcast persist throughout a frame, so you cannot just switch the palette after drawing a texture. If you want to use multiple paletted textures with different palettes, you will have to put their palette into a different part of the global palette. The global palette has 1024 entries, 8-bit paletted textures use 256 entries each. The KOS function ''timer_ms_gettime64()'' is used for animation of the characters depending on how much time has elapsed. /* Draw UI */ draw_sprite(&ui_sheet, "stage_announce", 174, 100, ui_palette_number); /* Health bar background */ draw_sprite(&ui_sheet, "barbg_left", 10, 10, 0); for(int x = 0; x < 100; ++x) draw_sprite(&ui_sheet, "barbg_mid", 15+x, 10, 0); draw_sprite(&ui_sheet, "barbg_right", 115, 10, 0); /* Draw animated health bar inside */ float const s = sin(0.001f * timer_ms_gettime64()); uint8_t health_count = 15 + 70 * s*s; draw_sprite(&ui_sheet, "healthbar_left", 16, 18, 0); for(int x = 0; x < health_count; ++x) draw_sprite(&ui_sheet, "healthbar_mid", 16+5 + x, 18, 0); draw_sprite(&ui_sheet, "healthbar_right", 16+5 + health_count, 18, 0); /* Draw animated enemies */ uint8_t sprite_number = (unsigned)(0.01f * timer_ms_gettime64()) % 8; char sprite_name[32]; snprintf(sprite_name, sizeof(sprite_name), "mage_combat%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 100, 300, stage1_actors_palette_number); snprintf(sprite_name, sizeof(sprite_name), "mage_shadowform%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 250, 300, stage1_actors_palette_number); snprintf(sprite_name, sizeof(sprite_name), "mage_idle%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 350, 300, stage1_actors_palette_number); After this the scene is drawn, so the PVR needs to be told to present the result: pvr_scene_finish(); } === Spritesheet Loader === The loading code can be found in int spritesheet_load( struct spritesheet * const spritesheet, /* Where to store the loaded information */ char const * const image_filename, /* foo.dtex */ char const * const palette_filename, /* foo.dtex.pal */ char const * const sheet_filename); /* foo.txt */ This function reads the ''foo.dtex'' texture and loads it into video memory. To allocate video memory you should use the KOS function ''pvr_mem_malloc()''. It will also load the corresponding palette file into memory. The DTEX and DPAL file formats are documented in texconv's readme. Lastly this function parses the sprite geometry information from the accompanying ''.txt'' file that TexturePacker created. The amount of lines in the file tells us the amount of sprites in the spritesheet. It is parsed in the following way: struct sprite * sprite = sprites; for(uint16_t i = 0; i < sprite_count && !feof(sheet_file); ++i) { int scanned = fscanf(sheet_file, "%[^,], %hu, %hu, %hu, %hu, 0, 0, 0, 0\n", sprite->name, &sprite->x, &sprite->y, &sprite->width, &sprite->height); printf("scanned %d parameters: %s %d %d %d %d\n", scanned, sprite->name, sprite->x, sprite->y, sprite->width, sprite->height); if(scanned != 5) { result = 10; goto cleanup; } ++sprite; } ''%[^,]'' is a quite underused format in ''scanf''. It means ''a string without ,''. So all this does is read a name that can be used in ''draw_sprite()'', as well as x and y offset and width and height of the sprite. === Speciyfing the Palette === This is done in ''setup_palette()'' and is very simple. Just keep in mind that multiple textures' palettes share the global palette memory. So some housekeeping needs to be performed to avoid overwriting palette memory that's used by other textures. You can also give a texture a different palette to create some amazing [http://www.effectgames.com/demos/canvascycle palette animations]. We leave the first 256 entries to what we'll call palette 0 and the next 256 to palette 1. void setup_palette(uint32_t const * colors, uint16_t count, uint8_t palette_number) { pvr_set_pal_format(PVR_PAL_ARGB8888); for(uint16_t i = 0; i < count; ++i) pvr_set_pal_entry(i + '''256 * palette_number''', colors[i]); } === Drawing sprites === This is done in ''draw_sprite()'' and is used as seen before in ''draw()''. void draw_sprite(struct spritesheet const * const sheet, char const * const name, float x, float y, uint8_t palette_number) { Remember that the palette must have been set up before, so this function is told which part of the global palette memory is being used. First we look up the information about the particular sprite called ''name'' we are tasked to draw. You might want to do this using a hashmap, I did a simple array walk. /* Find sprite by name */ uint16_t const sprite_count = sheet->sprite_count; struct sprite const * const sprites = sheet->sprites; struct sprite const * sprite = NULL; for(uint16_t i = 0; i < sprite_count; ++i) { if(!strcmp(sprites[i].name, name)) { sprite = &sprites[i]; break; } } if(sprite == NULL) { printf("There is no sprite named '%s' in this spritesheet.\n", name); return; } This gives us a pointer to a struct of the following form: struct sprite { char name[32]; uint16_t x, y, width, height; }; We'll be using this information to calculate the proper UV-coordinates. The whole texture of the entire spritesheet has coordinates on the horizontal axis in the range U=[0.0, 1.0] and the vertical axis V=[0.0, 1.0]. Therefore we can determine the UV-coordinates of this particular tile by the following calculation: float x0 = x; /* function arguments: where to draw the sprite on screen */ float y0 = y; float x1 = x + sprite->width; float y1 = y + sprite->height; float z = 1; float u0 = sprite->x / (float)sheet->width; /* Relative coordinates, [0.0,1.0] range */ float v0 = sprite->y / (float)sheet->height; float u1 = (sprite->x + sprite->width) / (float)sheet->width; float v1 = (sprite->y + sprite->height) / (float)sheet->height; As a little extra, I will not use polygons to draw the sprites. We'll be using the Dreamcast's special ''sprite drawing mode''. In sprite drawing mode, you specify the minimum and maximum values of the rectangle and its texture coordinates, instead of specifying each point. This works because sprites cannot be rotated. These sprites also cannot have a color. This makes them super efficient (for bullet hell games etc.), but you will need to use 3D polygons for 3D effects. Define which palette, texture and polyon list are to be used (punchthru for alpha masking here). Filtering is disabled because sprites are displayed 1:1. pvr_sprite_cxt_t sprite_context; /* This is just a convenience function for creating the following. */ pvr_sprite_hdr_t sprite_header; /* This is sent to the PVR before geometry is sent. */ pvr_sprite_cxt_txr(&sprite_context, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(palette_number), sheet->width, sheet->height, sheet->texture, PVR_FILTER_NONE); pvr_sprite_compile(&sprite_header, &sprite_context); pvr_prim(&sprite_header, sizeof(sprite_header)); /* Send header to PVR */ pvr_sprite_txr_t vert = { .flags = PVR_CMD_VERTEX_EOL, .ax = x0, .ay = y0, .az = z, .bx = x1, .by = y0, .bz = z, .cx = x1, .cy = y1, .cz = z, .dx = x0, .dy = y1, .auv = PVR_PACK_16BIT_UV(u0, v0), .buv = PVR_PACK_16BIT_UV(u1, v0), .cuv = PVR_PACK_16BIT_UV(u1, v1), }; pvr_prim(&vert, sizeof(vert)); } As you see it took only 2 calls to ''pvr_prim()'' to send a sprite. That said, ''pvr_prim()'' is not an efficient way of sending geometry to the PVR graphics chip. If you want to make a bullet hell game with a serious amount of sprites, you should look into ''store queues'' to transfer whole arrays of sprites. The header only needs to be set once before drawing sprites too. ==== PVR Sprite Draw Mode Caveat ==== While the ''triangle strip drawing mode'' of the PVR uses 32 bit floating point values for the texture coordinates, the ''sprite draw mode'' requires you to use 16 bit floating point values. If you don't position your sprites carefully, you will therefore see the following problem (note the distortion in the right character's animation): [[file:spritesheet_tutorial_demo_sprite.gif]] To fix this you will either need to position the sprites so that 16 bit floats can represent the texture coordinate properly, or you can use polygon drawing mode instead. I implemented this in the tutorial as well and polygon drawing mode is used by default. 621079baab2221222b5fc119e9e421bf93868cf5 350 343 2020-01-11T03:41:33Z Unknown user 0 Darc moved page [[Wiki/PVR Spritesheets]] to [[PVR Spritesheets]] wikitext text/x-wiki = About this tutorial = In this tutorial you will learn: * Generating a spritesheet from a directory full of single images automatically. * Converting the spritesheet into a PVR paletted texture automatically. * Loading the spritesheet into the PVR for drawing. * Setting up the palette for drawing. * Drawing a user interface (with a dynamic health bar). * Drawing animated characters. * Using the PVR's sprite drawing mode (instead of polygons) This will be the end result: [[File:Spritesheet_tutorial.gif]] = Required software = Before you can get started, you will need to install two tools. == TexturePacker == The first tool you need is [https://www.codeandweb.com/texturepacker/download TexturePacker]. It packs single images together into one big spritesheet, so you don't need to do this manually. We will make it do it for us using Make. TexturePacker has some Pro features, but this tutorial limits itself to its free features. This image should give you an idea about this tools's usefulness: [[File:Spritesheet_tutorial_texturepacker.png]] It will also create text files of the following format: mage_combat6, 244, 103, 122, 103, 0, 0, 0, 0 mage_combat7, 366, 103, 122, 103, 0, 0, 0, 0 mage_idle0, 0, 206, 79, 93, 0, 0, 0, 0 mage_idle1, 79, 206, 79, 94, 0, 0, 0, 0 mage_idle2, 158, 206, 82, 94, 0, 0, 0, 0 mage_idle3, 240, 206, 85, 94, 0, 0, 0, 0 The example code will parse this information to find out where each sprite within the spritesheet is. == texconv == The next tool you need is [https://github.com/tvspelsfreak/texconv texconv] by tvspelsfreak. ''texconv'' is an alternative to KOS' ''vqenc'' for converting images such as PNG into texture formats supported by the Dreamcast's PVR graphics chip. It doesn't create KMG files, instead it creates its own DTEX format, but provides other nice features. For this tutorial paletted textures are essential. Another feature that is used is its preview feature. It will basically convert the converted texture back to PNG so you can check the quality of the conversion. texconv has a dependency on Qt5, so install that first. On Debian-based systems this will get you running: sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make You can then use ''./texconv''. I suggest you put it somewhere in your ''PATH'' for convenient global access. texconv offers the following options (options used in this tutorial are marked as '''bold'''): Usage: ./texconv [options] Texture formats: BUMPMAP PAL4BPP ARGB4444 YUV422 ARGB1555 RGB565 '''PAL8BPP''' Options: -h, --help Displays this help. '''-i, --in <filename> Input file(s). (REQUIRED)''' '''-o, --out <filename> Output file. (REQUIRED)''' '''-f, --format <format> Texture format. (REQUIRED)''' -m, --mipmap Generate/allow mipmaps. -c, --compress Output a compressed texture. -s, --stride Output a stride texture. '''-p, --preview <filename> Generate a texture preview.''' -v, --verbose Extra printouts. -n, --nearest Use nearest-neighbor filtering for scaling mipmaps. -b, --bilinear Use bilinear filtering for scaling mipmaps. --vqcodeusage <filename> Output an image that visualizes compression code usage. = Downloading and running the example code = After installing the required software, you can download [[:File:Kos spritesheet tutorial.zip|the example source code for this tutorial]]. Unzip the archive and open the directory ''kos_spritesheet_tutorial''. You will find the following directory and file structure: * ''assets'': Raw art assets that will be turned into spritesheets and converted to Dreamcast PVR textures. * ''build'': Contains temporary files. For example ''build/ui_sheet.png'' will contain all art assets from ''assets/spritesheets/ui/*''. * ''main.c'': Loading, parsing and drawing code. * ''Makefile'': Build system. Also calls ''TexturePacker'' and ''texconv'' to create the spritesheets automatically upong changing anything. * ''readme.txt'': License for the used artwork. * ''romdisk'': Contains the files that will be available at runtime of the game. After typing ''make'', you should get the following output: kos-cc -std=c11 -c main.c -o main.o Generating spritesheet build/stage1_actors_sheet.png from assets/spritesheets/stage1_actors TexturePacker --sheet build/stage1_actors_sheet.png \ --format gideros --data romdisk/stage1_actors_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ assets/spritesheets/stage1_actors Resulting sprite sheet is 512x1024 Writing sprite sheet to build/stage1_actors_sheet.png Writing romdisk/stage1_actors_sheet.txt Converting romdisk/stage1_actors_sheet.dtex < build/stage1_actors_sheet.png texconv -i build/stage1_actors_sheet.png -o romdisk/stage1_actors_sheet.dtex -f PAL8BPP -p build/stage1_actors_preview.png Generating spritesheet build/ui_sheet.png from assets/spritesheets/ui TexturePacker --sheet build/ui_sheet.png \ --format gideros --data romdisk/ui_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ assets/spritesheets/ui Resulting sprite sheet is 512x128 Writing sprite sheet to build/ui_sheet.png Writing romdisk/ui_sheet.txt Converting romdisk/ui_sheet.dtex < build/ui_sheet.png texconv -i build/ui_sheet.png -o romdisk/ui_sheet.dtex -f PAL8BPP -p build/ui_preview.png /opt/toolchains/dc/kos/utils/genromfs/genromfs -f romdisk.img -d romdisk -v 0 rom 56ef0c99 [0xffffffff, 0xffffffff] 37777777777, sz 0, at 0x0 1 . [0x802 , 0x566411 ] 0040755, sz 0, at 0x20 1 .. [0x802 , 0x56639f ] 0040755, sz 0, at 0x40 [link to 0x20 ] 1 ui_sheet.dtex.pal [0x802 , 0x5654fa ] 0100644, sz 1032, at 0x60 1 ui_sheet.txt [0x802 , 0x5654f7 ] 0100644, sz 392, at 0x4a0 1 stage1_actors_sheet.dtex [0x802 , 0x5654f3 ] 0100644, sz 524304, at 0x650 1 stage1_actors_sheet.dtex.pal [0x802 , 0x5654f4 ] 0100644, sz 104, at 0x80690 1 stage1_actors_sheet.txt [0x802 , 0x5654f2 ] 0100644, sz 1818, at 0x80730 1 ui_sheet.dtex [0x802 , 0x5654f8 ] 0100644, sz 65552, at 0x80e80 /opt/toolchains/dc/kos/utils/bin2o/bin2o romdisk.img romdisk romdisk.o kos-cc -o spritesheet.elf main.o romdisk.o -lkmg -lkosutils -lm The executable will be called ''spritesheet.elf'' and can be run in an emulator or on your Dreamcast. = Explanation = The Makefile and main.c are heavily commented, so I will only refer to the most important bits here. == Makefile == If any of these rules confuse you, compare them to the output of the ''make'' command above and things should become clear. The Makefile target spritesheet.elf (the executable of the game) depends on romdisk.o, which depends on romdisk.img. All the converted spritesheets, their palettes, and the sprite geometry info will be stored in this romdisk, therefore romdisk.img must depend on those files. We don't care about the raw art assets, however, since they're not used at runtime. To achieve this in Make, the name of all spritesheets needs to be generated first, i.e. ''assets/spritesheets/foo/*.png assets/spritesheets/bar/*.png'' needs to turn into ''foo bar'' SPRITESHEET_NAMES := $(notdir $(wildcard assets/spritesheets/*)) Now ''romdisk.img'' should depend on ''romdisk/foo_sheet.dtex'' and ''romdisk/bar_sheet.dtex''. But ''texconv'' will save the palette file separately, so we add ''romdisk/foo_sheet.dtex.pal'' etc. SPRITESHEET_RESULT_FILES := $(patsubst %,romdisk/%_sheet.dtex,$(SPRITESHEET_NAMES)) romdisk.img: $(SPRITESHEET_RESULT_FILES) $(addsuffix .pal,$(SPRITESHEET_RESULT_FILES)) $(KOS_GENROMFS) -f romdisk.img -d romdisk -v Next Make needs to know how to generate the dtex and dtex.pal files from the corresponding PNG using ''texconv''. romdisk/%_sheet.dtex romdisk/%_sheet.dtex.pal: build/%_sheet.png $(info Converting $@ < $<) texconv -i $< -o $@ -f PAL8BPP -p build/$*_preview.png This rule requires that the sprites have been assembled as ''build/foo_sheet.png'' before (using TexturePacker), so that file becomes a dependency. Notice how the texture format is set to PAL8BPP, allowing for 256 different colors in the palette. PAL4BPP is also a possibility. texconv assumes 32 bit colors in the palette. It implicitly creates the ''.dtex.pal'' file. Also take a look at the ''build/foo_preview.png'' file to see whether you suffered quality loss during the conversion. This will happen if your input image has more than 256 colors in this case. Lastly TexturePacker is called to turn all images in the directory ''assets/spritesheets/foo/'' into ''build/foo_sheet.png'' and generate ''romdisk/foo_sheet.txt'' with the sprite geometry information. The txt file is stored in ''romdisk/'' because we will parse it during runtime in order to draw the sprites. ''build/foo_sheet.png'' is just the temporary file to create the Dreamcast PVR texture ''romdisk/foo_sheet.dtex'' (and ''.pal''). TexturePacker is instructed to create power-of-two textures (e.g. 64x256) of maximum dimensions 1024x1024, because of the PVR graphics chip's limitations. The options in the last line are necessary to disable pro-version features (otherwise TexturePacker will turn some sprites red). build/%_sheet.png: assets/spritesheets/% $(info Generating spritesheet $@ from $^) TexturePacker --sheet $@ \ --format gideros --data romdisk/$*_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ $^ == The code == I'll explain the code top-down, to give you a high level view. So assume that the mentioned helper functions have already been written, they will be explained later. === The main loop === The main loop is very basic: struct spritesheet stage1_actors_sheet, ui_sheet; int main(int argc, char *argv[]) { int result = 0; if(init()) { puts("Cannot init"); result = 1; goto cleanup; } for(;;) { draw(); } cleanup: spritesheet_free(&stage1_actors_sheet); spritesheet_free(&ui_sheet); return result; } Two spritesheets are loaded within init() as global variables. Then draw() will draw some sprites on the screen repeatedly. In the end some clean-up code is called (here only if init() fails). === The drawing routine === This is the draw() function. First it needs to wait for the PVR graphics chip to be ready for drawing: static void draw() { pvr_wait_ready(); /* Await v-blank */ pvr_scene_begin(); Next, the PVR is told to expect a punchthru polygon list. This will allow you to send geometry that can have translucency per pixel (visible or not, not half, unlike transparency). If you want to send opaque or transparent polygons too, you need to do that before this code. This function implicitly closes the preceding polygon lists for the duration of this frame. pvr_list_begin(PVR_LIST_PT_POLY); Now we set up the palettes for this frame. We tell the PVR chip what colors the textures refer to (try mixing them up for fun!). Here, draw() uses my helper function setup_palette(): void setup_palette(uint32_t const * colors, uint16_t count, uint8_t palette_number); // in draw() uint8_t const ui_palette_number = 0; uint8_t const stage1_actors_palette_number = 1; setup_palette(ui_sheet.palette, ui_sheet.color_count, ui_palette_number); setup_palette(stage1_actors_sheet.palette, stage1_actors_sheet.color_count, stage1_actors_palette_number); Now the actual sprite drawing happens. We draw a little user interface and some animated characters using my helper function draw_sprite(): void draw_sprite(struct spritesheet const * const sheet, char const * const name, float x, float y, uint8_t palette_number); The arguments are * a spritesheet struct with parsed information, * the name of the sprite inside of it that should be drawn (e.g. ''healthbar_left'' in ''romdisk/ui_sheet.txt'') * x, y coordinates on screen (y goes downwards) * The number of the palette to use. Palettes on the Dreamcast persist throughout a frame, so you cannot just switch the palette after drawing a texture. If you want to use multiple paletted textures with different palettes, you will have to put their palette into a different part of the global palette. The global palette has 1024 entries, 8-bit paletted textures use 256 entries each. The KOS function ''timer_ms_gettime64()'' is used for animation of the characters depending on how much time has elapsed. /* Draw UI */ draw_sprite(&ui_sheet, "stage_announce", 174, 100, ui_palette_number); /* Health bar background */ draw_sprite(&ui_sheet, "barbg_left", 10, 10, 0); for(int x = 0; x < 100; ++x) draw_sprite(&ui_sheet, "barbg_mid", 15+x, 10, 0); draw_sprite(&ui_sheet, "barbg_right", 115, 10, 0); /* Draw animated health bar inside */ float const s = sin(0.001f * timer_ms_gettime64()); uint8_t health_count = 15 + 70 * s*s; draw_sprite(&ui_sheet, "healthbar_left", 16, 18, 0); for(int x = 0; x < health_count; ++x) draw_sprite(&ui_sheet, "healthbar_mid", 16+5 + x, 18, 0); draw_sprite(&ui_sheet, "healthbar_right", 16+5 + health_count, 18, 0); /* Draw animated enemies */ uint8_t sprite_number = (unsigned)(0.01f * timer_ms_gettime64()) % 8; char sprite_name[32]; snprintf(sprite_name, sizeof(sprite_name), "mage_combat%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 100, 300, stage1_actors_palette_number); snprintf(sprite_name, sizeof(sprite_name), "mage_shadowform%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 250, 300, stage1_actors_palette_number); snprintf(sprite_name, sizeof(sprite_name), "mage_idle%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 350, 300, stage1_actors_palette_number); After this the scene is drawn, so the PVR needs to be told to present the result: pvr_scene_finish(); } === Spritesheet Loader === The loading code can be found in int spritesheet_load( struct spritesheet * const spritesheet, /* Where to store the loaded information */ char const * const image_filename, /* foo.dtex */ char const * const palette_filename, /* foo.dtex.pal */ char const * const sheet_filename); /* foo.txt */ This function reads the ''foo.dtex'' texture and loads it into video memory. To allocate video memory you should use the KOS function ''pvr_mem_malloc()''. It will also load the corresponding palette file into memory. The DTEX and DPAL file formats are documented in texconv's readme. Lastly this function parses the sprite geometry information from the accompanying ''.txt'' file that TexturePacker created. The amount of lines in the file tells us the amount of sprites in the spritesheet. It is parsed in the following way: struct sprite * sprite = sprites; for(uint16_t i = 0; i < sprite_count && !feof(sheet_file); ++i) { int scanned = fscanf(sheet_file, "%[^,], %hu, %hu, %hu, %hu, 0, 0, 0, 0\n", sprite->name, &sprite->x, &sprite->y, &sprite->width, &sprite->height); printf("scanned %d parameters: %s %d %d %d %d\n", scanned, sprite->name, sprite->x, sprite->y, sprite->width, sprite->height); if(scanned != 5) { result = 10; goto cleanup; } ++sprite; } ''%[^,]'' is a quite underused format in ''scanf''. It means ''a string without ,''. So all this does is read a name that can be used in ''draw_sprite()'', as well as x and y offset and width and height of the sprite. === Speciyfing the Palette === This is done in ''setup_palette()'' and is very simple. Just keep in mind that multiple textures' palettes share the global palette memory. So some housekeeping needs to be performed to avoid overwriting palette memory that's used by other textures. You can also give a texture a different palette to create some amazing [http://www.effectgames.com/demos/canvascycle palette animations]. We leave the first 256 entries to what we'll call palette 0 and the next 256 to palette 1. void setup_palette(uint32_t const * colors, uint16_t count, uint8_t palette_number) { pvr_set_pal_format(PVR_PAL_ARGB8888); for(uint16_t i = 0; i < count; ++i) pvr_set_pal_entry(i + '''256 * palette_number''', colors[i]); } === Drawing sprites === This is done in ''draw_sprite()'' and is used as seen before in ''draw()''. void draw_sprite(struct spritesheet const * const sheet, char const * const name, float x, float y, uint8_t palette_number) { Remember that the palette must have been set up before, so this function is told which part of the global palette memory is being used. First we look up the information about the particular sprite called ''name'' we are tasked to draw. You might want to do this using a hashmap, I did a simple array walk. /* Find sprite by name */ uint16_t const sprite_count = sheet->sprite_count; struct sprite const * const sprites = sheet->sprites; struct sprite const * sprite = NULL; for(uint16_t i = 0; i < sprite_count; ++i) { if(!strcmp(sprites[i].name, name)) { sprite = &sprites[i]; break; } } if(sprite == NULL) { printf("There is no sprite named '%s' in this spritesheet.\n", name); return; } This gives us a pointer to a struct of the following form: struct sprite { char name[32]; uint16_t x, y, width, height; }; We'll be using this information to calculate the proper UV-coordinates. The whole texture of the entire spritesheet has coordinates on the horizontal axis in the range U=[0.0, 1.0] and the vertical axis V=[0.0, 1.0]. Therefore we can determine the UV-coordinates of this particular tile by the following calculation: float x0 = x; /* function arguments: where to draw the sprite on screen */ float y0 = y; float x1 = x + sprite->width; float y1 = y + sprite->height; float z = 1; float u0 = sprite->x / (float)sheet->width; /* Relative coordinates, [0.0,1.0] range */ float v0 = sprite->y / (float)sheet->height; float u1 = (sprite->x + sprite->width) / (float)sheet->width; float v1 = (sprite->y + sprite->height) / (float)sheet->height; As a little extra, I will not use polygons to draw the sprites. We'll be using the Dreamcast's special ''sprite drawing mode''. In sprite drawing mode, you specify the minimum and maximum values of the rectangle and its texture coordinates, instead of specifying each point. This works because sprites cannot be rotated. These sprites also cannot have a color. This makes them super efficient (for bullet hell games etc.), but you will need to use 3D polygons for 3D effects. Define which palette, texture and polyon list are to be used (punchthru for alpha masking here). Filtering is disabled because sprites are displayed 1:1. pvr_sprite_cxt_t sprite_context; /* This is just a convenience function for creating the following. */ pvr_sprite_hdr_t sprite_header; /* This is sent to the PVR before geometry is sent. */ pvr_sprite_cxt_txr(&sprite_context, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(palette_number), sheet->width, sheet->height, sheet->texture, PVR_FILTER_NONE); pvr_sprite_compile(&sprite_header, &sprite_context); pvr_prim(&sprite_header, sizeof(sprite_header)); /* Send header to PVR */ pvr_sprite_txr_t vert = { .flags = PVR_CMD_VERTEX_EOL, .ax = x0, .ay = y0, .az = z, .bx = x1, .by = y0, .bz = z, .cx = x1, .cy = y1, .cz = z, .dx = x0, .dy = y1, .auv = PVR_PACK_16BIT_UV(u0, v0), .buv = PVR_PACK_16BIT_UV(u1, v0), .cuv = PVR_PACK_16BIT_UV(u1, v1), }; pvr_prim(&vert, sizeof(vert)); } As you see it took only 2 calls to ''pvr_prim()'' to send a sprite. That said, ''pvr_prim()'' is not an efficient way of sending geometry to the PVR graphics chip. If you want to make a bullet hell game with a serious amount of sprites, you should look into ''store queues'' to transfer whole arrays of sprites. The header only needs to be set once before drawing sprites too. ==== PVR Sprite Draw Mode Caveat ==== While the ''triangle strip drawing mode'' of the PVR uses 32 bit floating point values for the texture coordinates, the ''sprite draw mode'' requires you to use 16 bit floating point values. If you don't position your sprites carefully, you will therefore see the following problem (note the distortion in the right character's animation): [[file:spritesheet_tutorial_demo_sprite.gif]] To fix this you will either need to position the sprites so that 16 bit floats can represent the texture coordinate properly, or you can use polygon drawing mode instead. I implemented this in the tutorial as well and polygon drawing mode is used by default. 621079baab2221222b5fc119e9e421bf93868cf5 363 350 2020-01-11T03:51:21Z Unknown user 0 wikitext text/x-wiki Author: Bogglez = About this tutorial = In this tutorial you will learn: * Generating a spritesheet from a directory full of single images automatically. * Converting the spritesheet into a PVR paletted texture automatically. * Loading the spritesheet into the PVR for drawing. * Setting up the palette for drawing. * Drawing a user interface (with a dynamic health bar). * Drawing animated characters. * Using the PVR's sprite drawing mode (instead of polygons) This will be the end result: [[File:Spritesheet_tutorial.gif]] = Required software = Before you can get started, you will need to install two tools. == TexturePacker == The first tool you need is [https://www.codeandweb.com/texturepacker/download TexturePacker]. It packs single images together into one big spritesheet, so you don't need to do this manually. We will make it do it for us using Make. TexturePacker has some Pro features, but this tutorial limits itself to its free features. This image should give you an idea about this tools's usefulness: [[File:Spritesheet_tutorial_texturepacker.png]] It will also create text files of the following format: mage_combat6, 244, 103, 122, 103, 0, 0, 0, 0 mage_combat7, 366, 103, 122, 103, 0, 0, 0, 0 mage_idle0, 0, 206, 79, 93, 0, 0, 0, 0 mage_idle1, 79, 206, 79, 94, 0, 0, 0, 0 mage_idle2, 158, 206, 82, 94, 0, 0, 0, 0 mage_idle3, 240, 206, 85, 94, 0, 0, 0, 0 The example code will parse this information to find out where each sprite within the spritesheet is. == texconv == The next tool you need is [https://github.com/tvspelsfreak/texconv texconv] by tvspelsfreak. ''texconv'' is an alternative to KOS' ''vqenc'' for converting images such as PNG into texture formats supported by the Dreamcast's PVR graphics chip. It doesn't create KMG files, instead it creates its own DTEX format, but provides other nice features. For this tutorial paletted textures are essential. Another feature that is used is its preview feature. It will basically convert the converted texture back to PNG so you can check the quality of the conversion. texconv has a dependency on Qt5, so install that first. On Debian-based systems this will get you running: sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make You can then use ''./texconv''. I suggest you put it somewhere in your ''PATH'' for convenient global access. texconv offers the following options (options used in this tutorial are marked as '''bold'''): Usage: ./texconv [options] Texture formats: BUMPMAP PAL4BPP ARGB4444 YUV422 ARGB1555 RGB565 '''PAL8BPP''' Options: -h, --help Displays this help. '''-i, --in <filename> Input file(s). (REQUIRED)''' '''-o, --out <filename> Output file. (REQUIRED)''' '''-f, --format <format> Texture format. (REQUIRED)''' -m, --mipmap Generate/allow mipmaps. -c, --compress Output a compressed texture. -s, --stride Output a stride texture. '''-p, --preview <filename> Generate a texture preview.''' -v, --verbose Extra printouts. -n, --nearest Use nearest-neighbor filtering for scaling mipmaps. -b, --bilinear Use bilinear filtering for scaling mipmaps. --vqcodeusage <filename> Output an image that visualizes compression code usage. = Downloading and running the example code = After installing the required software, you can download [[:File:Kos spritesheet tutorial.zip|the example source code for this tutorial]]. Unzip the archive and open the directory ''kos_spritesheet_tutorial''. You will find the following directory and file structure: * ''assets'': Raw art assets that will be turned into spritesheets and converted to Dreamcast PVR textures. * ''build'': Contains temporary files. For example ''build/ui_sheet.png'' will contain all art assets from ''assets/spritesheets/ui/*''. * ''main.c'': Loading, parsing and drawing code. * ''Makefile'': Build system. Also calls ''TexturePacker'' and ''texconv'' to create the spritesheets automatically upong changing anything. * ''readme.txt'': License for the used artwork. * ''romdisk'': Contains the files that will be available at runtime of the game. After typing ''make'', you should get the following output: kos-cc -std=c11 -c main.c -o main.o Generating spritesheet build/stage1_actors_sheet.png from assets/spritesheets/stage1_actors TexturePacker --sheet build/stage1_actors_sheet.png \ --format gideros --data romdisk/stage1_actors_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ assets/spritesheets/stage1_actors Resulting sprite sheet is 512x1024 Writing sprite sheet to build/stage1_actors_sheet.png Writing romdisk/stage1_actors_sheet.txt Converting romdisk/stage1_actors_sheet.dtex < build/stage1_actors_sheet.png texconv -i build/stage1_actors_sheet.png -o romdisk/stage1_actors_sheet.dtex -f PAL8BPP -p build/stage1_actors_preview.png Generating spritesheet build/ui_sheet.png from assets/spritesheets/ui TexturePacker --sheet build/ui_sheet.png \ --format gideros --data romdisk/ui_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ assets/spritesheets/ui Resulting sprite sheet is 512x128 Writing sprite sheet to build/ui_sheet.png Writing romdisk/ui_sheet.txt Converting romdisk/ui_sheet.dtex < build/ui_sheet.png texconv -i build/ui_sheet.png -o romdisk/ui_sheet.dtex -f PAL8BPP -p build/ui_preview.png /opt/toolchains/dc/kos/utils/genromfs/genromfs -f romdisk.img -d romdisk -v 0 rom 56ef0c99 [0xffffffff, 0xffffffff] 37777777777, sz 0, at 0x0 1 . [0x802 , 0x566411 ] 0040755, sz 0, at 0x20 1 .. [0x802 , 0x56639f ] 0040755, sz 0, at 0x40 [link to 0x20 ] 1 ui_sheet.dtex.pal [0x802 , 0x5654fa ] 0100644, sz 1032, at 0x60 1 ui_sheet.txt [0x802 , 0x5654f7 ] 0100644, sz 392, at 0x4a0 1 stage1_actors_sheet.dtex [0x802 , 0x5654f3 ] 0100644, sz 524304, at 0x650 1 stage1_actors_sheet.dtex.pal [0x802 , 0x5654f4 ] 0100644, sz 104, at 0x80690 1 stage1_actors_sheet.txt [0x802 , 0x5654f2 ] 0100644, sz 1818, at 0x80730 1 ui_sheet.dtex [0x802 , 0x5654f8 ] 0100644, sz 65552, at 0x80e80 /opt/toolchains/dc/kos/utils/bin2o/bin2o romdisk.img romdisk romdisk.o kos-cc -o spritesheet.elf main.o romdisk.o -lkmg -lkosutils -lm The executable will be called ''spritesheet.elf'' and can be run in an emulator or on your Dreamcast. = Explanation = The Makefile and main.c are heavily commented, so I will only refer to the most important bits here. == Makefile == If any of these rules confuse you, compare them to the output of the ''make'' command above and things should become clear. The Makefile target spritesheet.elf (the executable of the game) depends on romdisk.o, which depends on romdisk.img. All the converted spritesheets, their palettes, and the sprite geometry info will be stored in this romdisk, therefore romdisk.img must depend on those files. We don't care about the raw art assets, however, since they're not used at runtime. To achieve this in Make, the name of all spritesheets needs to be generated first, i.e. ''assets/spritesheets/foo/*.png assets/spritesheets/bar/*.png'' needs to turn into ''foo bar'' SPRITESHEET_NAMES := $(notdir $(wildcard assets/spritesheets/*)) Now ''romdisk.img'' should depend on ''romdisk/foo_sheet.dtex'' and ''romdisk/bar_sheet.dtex''. But ''texconv'' will save the palette file separately, so we add ''romdisk/foo_sheet.dtex.pal'' etc. SPRITESHEET_RESULT_FILES := $(patsubst %,romdisk/%_sheet.dtex,$(SPRITESHEET_NAMES)) romdisk.img: $(SPRITESHEET_RESULT_FILES) $(addsuffix .pal,$(SPRITESHEET_RESULT_FILES)) $(KOS_GENROMFS) -f romdisk.img -d romdisk -v Next Make needs to know how to generate the dtex and dtex.pal files from the corresponding PNG using ''texconv''. romdisk/%_sheet.dtex romdisk/%_sheet.dtex.pal: build/%_sheet.png $(info Converting $@ < $<) texconv -i $< -o $@ -f PAL8BPP -p build/$*_preview.png This rule requires that the sprites have been assembled as ''build/foo_sheet.png'' before (using TexturePacker), so that file becomes a dependency. Notice how the texture format is set to PAL8BPP, allowing for 256 different colors in the palette. PAL4BPP is also a possibility. texconv assumes 32 bit colors in the palette. It implicitly creates the ''.dtex.pal'' file. Also take a look at the ''build/foo_preview.png'' file to see whether you suffered quality loss during the conversion. This will happen if your input image has more than 256 colors in this case. Lastly TexturePacker is called to turn all images in the directory ''assets/spritesheets/foo/'' into ''build/foo_sheet.png'' and generate ''romdisk/foo_sheet.txt'' with the sprite geometry information. The txt file is stored in ''romdisk/'' because we will parse it during runtime in order to draw the sprites. ''build/foo_sheet.png'' is just the temporary file to create the Dreamcast PVR texture ''romdisk/foo_sheet.dtex'' (and ''.pal''). TexturePacker is instructed to create power-of-two textures (e.g. 64x256) of maximum dimensions 1024x1024, because of the PVR graphics chip's limitations. The options in the last line are necessary to disable pro-version features (otherwise TexturePacker will turn some sprites red). build/%_sheet.png: assets/spritesheets/% $(info Generating spritesheet $@ from $^) TexturePacker --sheet $@ \ --format gideros --data romdisk/$*_sheet.txt \ --size-constraints POT --max-width 1024 --max-height 1024 \ --pack-mode Best --disable-rotation --trim-mode None \ --trim-sprite-names \ --algorithm Basic --png-opt-level 0 --extrude 0 --disable-auto-alias \ $^ == The code == I'll explain the code top-down, to give you a high level view. So assume that the mentioned helper functions have already been written, they will be explained later. === The main loop === The main loop is very basic: struct spritesheet stage1_actors_sheet, ui_sheet; int main(int argc, char *argv[]) { int result = 0; if(init()) { puts("Cannot init"); result = 1; goto cleanup; } for(;;) { draw(); } cleanup: spritesheet_free(&stage1_actors_sheet); spritesheet_free(&ui_sheet); return result; } Two spritesheets are loaded within init() as global variables. Then draw() will draw some sprites on the screen repeatedly. In the end some clean-up code is called (here only if init() fails). === The drawing routine === This is the draw() function. First it needs to wait for the PVR graphics chip to be ready for drawing: static void draw() { pvr_wait_ready(); /* Await v-blank */ pvr_scene_begin(); Next, the PVR is told to expect a punchthru polygon list. This will allow you to send geometry that can have translucency per pixel (visible or not, not half, unlike transparency). If you want to send opaque or transparent polygons too, you need to do that before this code. This function implicitly closes the preceding polygon lists for the duration of this frame. pvr_list_begin(PVR_LIST_PT_POLY); Now we set up the palettes for this frame. We tell the PVR chip what colors the textures refer to (try mixing them up for fun!). Here, draw() uses my helper function setup_palette(): void setup_palette(uint32_t const * colors, uint16_t count, uint8_t palette_number); // in draw() uint8_t const ui_palette_number = 0; uint8_t const stage1_actors_palette_number = 1; setup_palette(ui_sheet.palette, ui_sheet.color_count, ui_palette_number); setup_palette(stage1_actors_sheet.palette, stage1_actors_sheet.color_count, stage1_actors_palette_number); Now the actual sprite drawing happens. We draw a little user interface and some animated characters using my helper function draw_sprite(): void draw_sprite(struct spritesheet const * const sheet, char const * const name, float x, float y, uint8_t palette_number); The arguments are * a spritesheet struct with parsed information, * the name of the sprite inside of it that should be drawn (e.g. ''healthbar_left'' in ''romdisk/ui_sheet.txt'') * x, y coordinates on screen (y goes downwards) * The number of the palette to use. Palettes on the Dreamcast persist throughout a frame, so you cannot just switch the palette after drawing a texture. If you want to use multiple paletted textures with different palettes, you will have to put their palette into a different part of the global palette. The global palette has 1024 entries, 8-bit paletted textures use 256 entries each. The KOS function ''timer_ms_gettime64()'' is used for animation of the characters depending on how much time has elapsed. /* Draw UI */ draw_sprite(&ui_sheet, "stage_announce", 174, 100, ui_palette_number); /* Health bar background */ draw_sprite(&ui_sheet, "barbg_left", 10, 10, 0); for(int x = 0; x < 100; ++x) draw_sprite(&ui_sheet, "barbg_mid", 15+x, 10, 0); draw_sprite(&ui_sheet, "barbg_right", 115, 10, 0); /* Draw animated health bar inside */ float const s = sin(0.001f * timer_ms_gettime64()); uint8_t health_count = 15 + 70 * s*s; draw_sprite(&ui_sheet, "healthbar_left", 16, 18, 0); for(int x = 0; x < health_count; ++x) draw_sprite(&ui_sheet, "healthbar_mid", 16+5 + x, 18, 0); draw_sprite(&ui_sheet, "healthbar_right", 16+5 + health_count, 18, 0); /* Draw animated enemies */ uint8_t sprite_number = (unsigned)(0.01f * timer_ms_gettime64()) % 8; char sprite_name[32]; snprintf(sprite_name, sizeof(sprite_name), "mage_combat%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 100, 300, stage1_actors_palette_number); snprintf(sprite_name, sizeof(sprite_name), "mage_shadowform%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 250, 300, stage1_actors_palette_number); snprintf(sprite_name, sizeof(sprite_name), "mage_idle%u", sprite_number); sprite_name[31] = 0; draw_sprite(&stage1_actors_sheet, sprite_name, 350, 300, stage1_actors_palette_number); After this the scene is drawn, so the PVR needs to be told to present the result: pvr_scene_finish(); } === Spritesheet Loader === The loading code can be found in int spritesheet_load( struct spritesheet * const spritesheet, /* Where to store the loaded information */ char const * const image_filename, /* foo.dtex */ char const * const palette_filename, /* foo.dtex.pal */ char const * const sheet_filename); /* foo.txt */ This function reads the ''foo.dtex'' texture and loads it into video memory. To allocate video memory you should use the KOS function ''pvr_mem_malloc()''. It will also load the corresponding palette file into memory. The DTEX and DPAL file formats are documented in texconv's readme. Lastly this function parses the sprite geometry information from the accompanying ''.txt'' file that TexturePacker created. The amount of lines in the file tells us the amount of sprites in the spritesheet. It is parsed in the following way: struct sprite * sprite = sprites; for(uint16_t i = 0; i < sprite_count && !feof(sheet_file); ++i) { int scanned = fscanf(sheet_file, "%[^,], %hu, %hu, %hu, %hu, 0, 0, 0, 0\n", sprite->name, &sprite->x, &sprite->y, &sprite->width, &sprite->height); printf("scanned %d parameters: %s %d %d %d %d\n", scanned, sprite->name, sprite->x, sprite->y, sprite->width, sprite->height); if(scanned != 5) { result = 10; goto cleanup; } ++sprite; } ''%[^,]'' is a quite underused format in ''scanf''. It means ''a string without ,''. So all this does is read a name that can be used in ''draw_sprite()'', as well as x and y offset and width and height of the sprite. === Speciyfing the Palette === This is done in ''setup_palette()'' and is very simple. Just keep in mind that multiple textures' palettes share the global palette memory. So some housekeeping needs to be performed to avoid overwriting palette memory that's used by other textures. You can also give a texture a different palette to create some amazing [http://www.effectgames.com/demos/canvascycle palette animations]. We leave the first 256 entries to what we'll call palette 0 and the next 256 to palette 1. void setup_palette(uint32_t const * colors, uint16_t count, uint8_t palette_number) { pvr_set_pal_format(PVR_PAL_ARGB8888); for(uint16_t i = 0; i < count; ++i) pvr_set_pal_entry(i + '''256 * palette_number''', colors[i]); } === Drawing sprites === This is done in ''draw_sprite()'' and is used as seen before in ''draw()''. void draw_sprite(struct spritesheet const * const sheet, char const * const name, float x, float y, uint8_t palette_number) { Remember that the palette must have been set up before, so this function is told which part of the global palette memory is being used. First we look up the information about the particular sprite called ''name'' we are tasked to draw. You might want to do this using a hashmap, I did a simple array walk. /* Find sprite by name */ uint16_t const sprite_count = sheet->sprite_count; struct sprite const * const sprites = sheet->sprites; struct sprite const * sprite = NULL; for(uint16_t i = 0; i < sprite_count; ++i) { if(!strcmp(sprites[i].name, name)) { sprite = &sprites[i]; break; } } if(sprite == NULL) { printf("There is no sprite named '%s' in this spritesheet.\n", name); return; } This gives us a pointer to a struct of the following form: struct sprite { char name[32]; uint16_t x, y, width, height; }; We'll be using this information to calculate the proper UV-coordinates. The whole texture of the entire spritesheet has coordinates on the horizontal axis in the range U=[0.0, 1.0] and the vertical axis V=[0.0, 1.0]. Therefore we can determine the UV-coordinates of this particular tile by the following calculation: float x0 = x; /* function arguments: where to draw the sprite on screen */ float y0 = y; float x1 = x + sprite->width; float y1 = y + sprite->height; float z = 1; float u0 = sprite->x / (float)sheet->width; /* Relative coordinates, [0.0,1.0] range */ float v0 = sprite->y / (float)sheet->height; float u1 = (sprite->x + sprite->width) / (float)sheet->width; float v1 = (sprite->y + sprite->height) / (float)sheet->height; As a little extra, I will not use polygons to draw the sprites. We'll be using the Dreamcast's special ''sprite drawing mode''. In sprite drawing mode, you specify the minimum and maximum values of the rectangle and its texture coordinates, instead of specifying each point. This works because sprites cannot be rotated. These sprites also cannot have a color. This makes them super efficient (for bullet hell games etc.), but you will need to use 3D polygons for 3D effects. Define which palette, texture and polyon list are to be used (punchthru for alpha masking here). Filtering is disabled because sprites are displayed 1:1. pvr_sprite_cxt_t sprite_context; /* This is just a convenience function for creating the following. */ pvr_sprite_hdr_t sprite_header; /* This is sent to the PVR before geometry is sent. */ pvr_sprite_cxt_txr(&sprite_context, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(palette_number), sheet->width, sheet->height, sheet->texture, PVR_FILTER_NONE); pvr_sprite_compile(&sprite_header, &sprite_context); pvr_prim(&sprite_header, sizeof(sprite_header)); /* Send header to PVR */ pvr_sprite_txr_t vert = { .flags = PVR_CMD_VERTEX_EOL, .ax = x0, .ay = y0, .az = z, .bx = x1, .by = y0, .bz = z, .cx = x1, .cy = y1, .cz = z, .dx = x0, .dy = y1, .auv = PVR_PACK_16BIT_UV(u0, v0), .buv = PVR_PACK_16BIT_UV(u1, v0), .cuv = PVR_PACK_16BIT_UV(u1, v1), }; pvr_prim(&vert, sizeof(vert)); } As you see it took only 2 calls to ''pvr_prim()'' to send a sprite. That said, ''pvr_prim()'' is not an efficient way of sending geometry to the PVR graphics chip. If you want to make a bullet hell game with a serious amount of sprites, you should look into ''store queues'' to transfer whole arrays of sprites. The header only needs to be set once before drawing sprites too. ==== PVR Sprite Draw Mode Caveat ==== While the ''triangle strip drawing mode'' of the PVR uses 32 bit floating point values for the texture coordinates, the ''sprite draw mode'' requires you to use 16 bit floating point values. If you don't position your sprites carefully, you will therefore see the following problem (note the distortion in the right character's animation): [[file:spritesheet_tutorial_demo_sprite.gif]] To fix this you will either need to position the sprites so that 16 bit floats can represent the texture coordinate properly, or you can use polygon drawing mode instead. I implemented this in the tutorial as well and polygon drawing mode is used by default. 74516b94eebb9664e97a99a457d22bb7331ed9cb Development 0 2 345 261 2020-01-11T03:37:39Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR ** [[Wiki/PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] f4d3e338a3c1a1579274cd0a69c5d73ba36256ed 352 345 2020-01-11T03:42:03Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] eee87eb5bce54331d45e1cdb56ff35ef3af25cd0 353 352 2020-01-11T03:43:53Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 89d05d47e8948e7ff8e9e17a1c057caba7be53d2 Serial interface 0 93 346 279 2020-01-11T03:37:42Z Unknown user 0 wikitext text/x-wiki The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. {| class="wikitable" |+Serial connector pinout |- ! Pin ! Description |- |1 | +5V |- |2 | ? |- |3 |Ground |- |4 |RX2 |- |5 |TX2 |- |6 |RTS |- |7 |CTS |- |8 | ? |- |9 | ? |- |10 | +3.3V |} {{DCWiki:Stub}} 524ff53f831a45b7fe931c288ac62d6dafc1672e 356 346 2020-01-11T03:46:42Z Unknown user 0 wikitext text/x-wiki The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. {| class="wikitable" |+Serial connector pinout |- ! Pin ! Description |- |1 | +5V |- |2 |SCK |- |3 |Ground |- |4 |RX2 |- |5 |TX2 |- |6 |RTS |- |7 |CTS |- |8 |Ground |- |9 |Reset |- |10 | +3.3V |} A SCIF loopback connection can be created to allow a Dreamcast to conduct and pass the SCIF test on the official Sega [[DC Checker]] diagnostics software by connecting pin 4 (RX2) to pin 5 (TXD) and connecting pin 6 (RTS) to pin 7 (CTS). {{DCWiki:Stub}} 9e7591e335cf5fa773bac1496a5072d65bf0229f Wiki/PVR Spritesheets 0 124 351 2020-01-11T03:41:33Z Unknown user 0 Darc moved page [[Wiki/PVR Spritesheets]] to [[PVR Spritesheets]] wikitext text/x-wiki #REDIRECT [[PVR Spritesheets]] 3127d0732df973db7c277571dda4984c71af8295 DCWiki:Software 4 81 354 297 2020-01-11T03:43:55Z Unknown user 0 Added VMU Emulators page wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[VMU Emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 2fa3fe22ef83e113c76f185accd21a6f3e06841e Romdisk Swapping 0 125 362 2020-01-11T03:50:37Z Unknown user 0 Created page with "Author: Lerabot = Introduction = When I started adding things to the ROM disk, I didn't realize that my 10MB+ .elf file would be problematic (i.e. not load) on the Dreamcast...." wikitext text/x-wiki Author: Lerabot = Introduction = When I started adding things to the ROM disk, I didn't realize that my 10MB+ .elf file would be problematic (i.e. not load) on the Dreamcast. Also it's been mentioned in a forum topic that loading a romdisk instead of multiple files would be faster. I also think that it could be a neat way to handle/manage your memory altogether. = Guide = == Step 1== Organizing the content or your romdisk in multiple folders: /level1 /level2 /level3 == Step 2 == In your Makefile, duplicate the usual romdisk generation command but change the romdisk name and directory. I also added GZip compression, however sometimes GZip-ed files fail to load. If thats the case for you then don't bother with GZip. romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d path/to/romdisk -v # <- this is the usual romdisk command, you can still keep this $(KOS_GENROMFS) -f romdisk_name.img -d path/to/romdisk_folder -v # <- this is your new romdisk, replace the romdisk_name and romdisk_folder with what you want. $(KOS_GENROMFS) -f level1.img -d path/to/level -v # <- if I'm using the exemple from earlier, I could make a "level1" romdisk this way gzip -f -9 romdisk_name.img # <-make sure you add all your new romdisk names here ''Note:'' the leading whitespace consists of a tab, not spaces. == Step 3 == In your code you'll need a way to load those new romdisks, we'll use this code snippet by ''BlackAura''. For more info, check this topic [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=68795&hilit=romdisk+feet+of+fury] #include <kos.h> #include <zlib/zlib.h> // Thanks BlackAura ;) int mount_romdisk(char *filename, char *mountpoint) { void *buffer; int length = zlib_getlength(filename); // Check failure if(length == 0) return 0; // Open file gzFile file = gzopen(filename, "rb"); if(!file) return 0; // Allocate memory, read file buffer = malloc(length); gzread(file, buffer, length); gzclose(file); // Mount fs_romdisk_mount(mountpoint, buffer, 1); return 1; } It is important that your mount point start with a '/' -> "/level1" and not "level1" You can now unload the romdisk using: fs_romdisk_unmount(mountpoint); = Usage with a Broadband adapter or dc-ipload = In order to use these new romdisk, you need to enable ''/pc'' redirection in your ''dc-tool'', update your ''dc-tool'' command to use ''-c'': dc-tool-ip -t dreamcast -c /path/to/project -x program_name.elf You can now use the function below to access files in the ''/rom'' folder: mount_romdisk("/pc/romdisk_name.img.gz", "/rom"); Keep in mind that you'll have to switch ''/pc/'' to ''/cd/'' when you burn this to a CD. d20b4d6a068fc8817f3d05f9c32554ab8e5dbf41 VMU emulators 0 118 367 366 2020-01-11T03:56:58Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : GyroVorbis (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android 990f5adf51067935a23a84f5cb4266ff4c3f16df 369 367 2020-01-11T03:58:47Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[GyroVorbis]] (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android 4f7fd3a0793e399097f364ffababb5183f02ec08 370 369 2020-01-11T03:59:11Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis]] (Falco Girgis), Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android 4d35cd14e6435fffe5d78ca6d850f9cdb8782089 371 370 2020-01-11T03:59:35Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis] Falco Girgis], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android ecc9eaa771d57d5334e3f8ad1030f0caf1bc1cde 372 371 2020-01-11T03:59:56Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android 0e050bd1a18e8ad0ffb461891ca725e1e946c8a5 373 372 2020-01-11T04:03:59Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official Page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official Page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android =Visual Memory Emulator= * Google Play : [https://play.google.com/store/apps/details?id=com.nuritsubushi.vmemu] * Developer : Kum * Compatibility : Unknown * Platform(s) : Android 254cf85c40e6d9a3393bce4b12fab6180477eb1f 374 373 2020-01-11T04:05:11Z Unknown user 0 Darc moved page [[VMU Emulators]] to [[VMU emulators]] wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official Page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= * Official Page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android =Visual Memory Emulator= * Google Play : [https://play.google.com/store/apps/details?id=com.nuritsubushi.vmemu] * Developer : Kum * Compatibility : Unknown * Platform(s) : Android 254cf85c40e6d9a3393bce4b12fab6180477eb1f 377 374 2020-01-11T04:11:39Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official Page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= The original VMU emulator, written by the man who helped to reverse engineer the platform and kickstart the homebrew scene. * Official Page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android =Visual Memory Emulator= * Google Play : [https://play.google.com/store/apps/details?id=com.nuritsubushi.vmemu] * Developer : Kum * Compatibility : Unknown * Platform(s) : Android 63d2b7ee881f90c464074bcbd52d05bb1a1e3854 VMU development 0 99 368 309 2020-01-11T03:58:13Z Unknown user 0 wikitext text/x-wiki Here are some reference resources to get started * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 0148fb331d41f5968a7d567c5c8d2bc374bb9e6d VMU Emulators 0 126 375 2020-01-11T04:05:11Z Unknown user 0 Darc moved page [[VMU Emulators]] to [[VMU emulators]] wikitext text/x-wiki #REDIRECT [[VMU emulators]] 25e72afc5ab48f510743e89493fd26f589451df3 DCWiki:Software 4 81 376 354 2020-01-11T04:05:36Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR Image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} d72eaa71754a68f0fb677726ced4c231b0fcf053 380 376 2020-01-11T04:25:14Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} b91fbf19ca98023bd19172eaa6bd06ae619e27b9 395 380 2020-01-11T10:04:53Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[Tools and Utilities]] * [[VMU development]] |} |} 71d22ad80b344e2155abf8477bca7566d033ed25 MR image 0 73 378 258 2020-01-11T04:25:05Z Unknown user 0 Darc moved page [[MR Image]] to [[MR image]] wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==File Structure== ==Encoding== ==Decoding== 8a8a5f9ad203cd07fb9176be267f8bd73c9238d0 384 378 2020-01-11T05:31:43Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==File Format== ===File Header=== A MR file starts with a 30 byte header. {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Filesize |- | 4 bytes || Crap |- | 4 bytes || Image Data offset |- | 4 bytes || Image Width |- | 4 bytes || Image Height |- | 4 bytes || Crap |- | 4 bytes || Amount of colors in palette |} ===Palette=== ==Encoding== ==Decoding== 5df2002d2d3448e2d631680e52a11d8084052a0f 385 384 2020-01-11T06:44:04Z Unknown user 0 /* File Format */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br><br> ==File Format== A MR file starts off with a 30 byte header. ===File Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total Filesize |- | 4 bytes || Crap |- | 4 bytes || Image Data offset (Header size + Palette size) |- | 4 bytes || Image Width |- | 4 bytes || Image Height |- | 4 bytes || Crap |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using RLE. ==Encoding== ==Decoding== 19a03ac6ddb70811c2ee0f41b675599d523fec58 386 385 2020-01-11T07:09:24Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. <br/> '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br/> ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using RLE. ==Encoding Algorithm== ==Decoding Algorithm== 6bcbd7a6418376bdd7cdc2e822733d9d6880dbc9 387 386 2020-01-11T07:25:28Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. <br/> '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br/> ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using a form of Run-Length Encoding (RLE). The pseudocode algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== ==Decoding Algorithm== 32f9b9e53b04b8382d80178f923757ba03092042 389 387 2020-01-11T08:20:43Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. <br/> '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various image formats. [ DOWNLOAD HERE] <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format GIMP supports. [https://gitlab.com/BBHoodsta/makeip] ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using a form of Run-Length Encoding (RLE). The pseudocode algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== ==Decoding Algorithm== 007a4ab258849df4967c5f965783bbb225ef4265 390 389 2020-01-11T08:24:10Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. <br/> '''MR Image must be:''' * 320x90 or less * Max 128 colors * Less than 8192 bytes to fit in a IP.BIN * The transparent color is #c0c0c0, or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using a form of Run-Length Encoding (RLE). The pseudocode algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== ==Decoding Algorithm== 349270d71e6a2b6265e6c50e17ff11dd90e27e4e 391 390 2020-01-11T08:25:19Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using a form of Run-Length Encoding (RLE). The pseudocode algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== ==Decoding Algorithm== 114ab94465bb60a83842cd5d8349bdc521ad104a 392 391 2020-01-11T08:34:12Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. Since [[IP.BIN]] is restricted to a 32k file size and the MR image must be inserted into that file in order to be displayed during the boot process, there are a couple of guidelines the MR image must meet to be shown during the boot process. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is compressed using a form of Run-Length Encoding (RLE). The pseudocode algorithms to encode/decode the image data are shown below. '''Encoding Algorithm''' '''Decoding Algorithm''' 8da94ee6a968844a14dbe1e693f411dd29542cab MR Image 0 127 379 2020-01-11T04:25:05Z Unknown user 0 Darc moved page [[MR Image]] to [[MR image]] wikitext text/x-wiki #REDIRECT [[MR image]] 9253fce4053e0b0cedbe442e6ed7ec4f89c19a03 Dreamcast emulators 0 4 381 131 2020-01-11T04:36:26Z Unknown user 0 Add WashingtonDC to the emulators page wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : skmp, others. Derived from nullDC. * Status : Active, Under rewrite * Platform : Android, Windows, Linux, OSX, html5 ### Supported feature ### Known issues - Extremely buggy ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues - No sound support for homebrew with HLE bios ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp, ZeZu, PsyMan * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ## Demul * Official page : [http://demul.emulation64.com/](http://demul.emulation64.com/) * Developed by : ?? * Status : Inactive * Platform : Windows ### Supported feature - MMU, Naomi 2 ### Known issues ## WashingtonDC * Official page: [http://washemu.org/](http://washemu.org/) * Developed by : snickerbockers * Status : Active * Platform : Linux, Windows ### Supported feature - Console support (printf) via serial port - remote GDB debugging ### Known issues - game compatibility - Z-Fighting 8f22769606d7836e23e016834afa20be4a4154b1 382 381 2020-01-11T04:38:32Z Unknown user 0 Add MAME to the emulators page wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : skmp, others. Derived from nullDC. * Status : Active, Under rewrite * Platform : Android, Windows, Linux, OSX, html5 ### Supported feature ### Known issues - Extremely buggy ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues - No sound support for homebrew with HLE bios ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp, ZeZu, PsyMan * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ## Demul * Official page : [http://demul.emulation64.com/](http://demul.emulation64.com/) * Developed by : ?? * Status : Inactive * Platform : Windows ### Supported feature - MMU, Naomi 2 ### Known issues ## WashingtonDC * Official page: [http://washemu.org/](http://washemu.org/) * Developed by : snickerbockers * Status : Active * Platform : Linux, Windows ### Supported feature - Console support (printf) via serial port - remote GDB debugging ### Known issues - game compatibility - Z-Fighting ## MAME * Official page: [http://mamedev.org/](http://mamedev.org/) * Developed by : MAME community * Status : Active * Platform : Linux, Windows ### Supported feature ### Known issues - game compatibility - speed cda93878bb8c8034be9ff1c1ef20312986d780a7 383 382 2020-01-11T05:17:13Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ## Reicast * Official page : [https://reicast.com](https://reicast.com) * Developed by : skmp, others. Derived from nullDC. * Status : Active, Under rewrite * Platform : Android, Windows, Linux, OSX, html5 ### Supported feature ### Known issues - Extremely buggy ## Redream * Official page : [https://redream.io](https://redream.io) * Developed by : inolen * Status : Active * Platform : Android, Windows, Linux, OSX ### Supported feature ### Known issues - No sound support for homebrew with HLE bios ## NullDC * Official page : [https://github.com/skmp/nulldc](https://github.com/skmp/nulldc) * Developed by : skmp, ZeZu, PsyMan * Status : Inactive * Platform : Windows ### Supported feature ### Known issues ## LXdream * Official page : [http://www.lxdream.org/news/](http://www.lxdream.org/news/) * Developed by : ?? * Status : Inactive * Platform : Linux ### Supported feature - ** DEV ** Console support (printf) ### Known issues ## Demul * Official page : [http://demul.emulation64.com/](http://demul.emulation64.com/) * Developed by : ?? * Status : Inactive * Platform : Windows ### Supported feature - MMU, Naomi 2 ### Known issues ## WashingtonDC * Official page: [http://washemu.org/](http://washemu.org/) * Developed by : snickerbockers * Status : Active * Platform : Linux, Windows ### Supported feature - Console support (printf) via serial port - remote GDB debugging ### Known issues - game compatibility - Z-Fighting ## MAME * Official page: [http://mamedev.org/](http://mamedev.org/) * Developed by : MAME community * Status : Active * Platform : Linux, Windows ### Supported feature ### Known issues - game compatibility - speed ## Other older emulators These emulators are listed mostly for historical/archival reasons. * [DreamEmu](http://www.dreamemu.net/) * [Dreamer](http://emulatronia.com/dcemu.htm) * Makaron * [Swirly](http://swirly.sourceforge.net/) 0d6ccdcbb15652cf36232b6e6c9a32b09849ecea User:Protofall 2 128 388 2020-01-11T07:37:40Z Unknown user 0 Created page with "I create homebrew for the Dreamcast. I've made a recreation of Minesweeper, a few dev tools and a Dr Mario clone called "Moving Day"" wikitext text/x-wiki I create homebrew for the Dreamcast. I've made a recreation of Minesweeper, a few dev tools and a Dr Mario clone called "Moving Day" 16d57561dcf2e17337cfb69ada42062a3ab21a06 File:Dcdis-0.4a.zip 6 129 393 2020-01-11T10:01:25Z Unknown user 0 dcdis 0.4a updated to ANSI C by MooptheHedgehog https://dcemulation.org/phpBB/viewtopic.php?f=29&t=105372 wikitext text/x-wiki == Summary == dcdis 0.4a updated to ANSI C by MooptheHedgehog https://dcemulation.org/phpBB/viewtopic.php?f=29&t=105372 dd885c44c644af98fb8e93dc50e36f2b423ed4e7 Dcdis 0 130 394 2020-01-11T10:02:16Z Unknown user 0 Created page with "[https://dcemulation.org/phpBB/viewtopic.php?f=29&t=105372 info] [[:File:Dcdis-0.4a.zip]] {{DCWiki:Stub}} {{DISPLAYTITLE:dcdis}}" wikitext text/x-wiki [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=105372 info] [[:File:Dcdis-0.4a.zip]] {{DCWiki:Stub}} {{DISPLAYTITLE:dcdis}} a0d7ff38c762f036e0729914a54bd7358504cf07 Tools and Utilities 0 131 396 2020-01-11T10:05:49Z Unknown user 0 Created page with "This article will list various tools and utilities for Dreamcast development and game hacking. * [[dcdis]] {{DCWiki:Stub}}" wikitext text/x-wiki This article will list various tools and utilities for Dreamcast development and game hacking. * [[dcdis]] {{DCWiki:Stub}} c37283ab008f8fb4d6ead3444718918c7fc32e63 Simulant 0 132 397 2020-01-11T12:48:19Z Unknown user 0 Created page with "'''Simulant''' is a cross-platform general-purpose game engine written in C++. It is designed with portability in mind, using minimal dependencies and targetting C++11 (rathe..." wikitext text/x-wiki '''Simulant''' is a cross-platform general-purpose game engine written in C++. It is designed with portability in mind, using minimal dependencies and targetting C++11 (rather than more modern versions of the language). The aim of Simulant is to create an easy-to-use game engine to allow building homebrew for older games consoles, as well as creating a great developer-experience on modern platforms. === Features === * Easy to use API, and getting simpler all the time! * Flexible rendering pipeline * Complex material scripting format * Loading of .obj models and the X-Wing vs Tie Fighter .opt format * Loading of MD2 animated models * Loading of Q2 BSP files (needs work) * Loading of heightmap terrains from image files * Advanced spatial hash partitioning and culling * Loading of JPG, PNG, TGA, WAL, PCX images and more! * Shortcut functions for loading 2D sprites, 2D backgrounds and 3D skyboxes * Simple scene graph functions * UI widgets (Button, Label, Progress Bar) * Basic rigid body physics using the Bounce library * Procedural functions for generating spheres, cubes, capsules, circles and rectangles * Functions for creating lights, multiple viewports and cameras {{DCWiki:Stub}} 2ab78d7798abd3beda7ff90bcd7ffc1a9f5da77b 398 397 2020-01-11T12:49:50Z Unknown user 0 wikitext text/x-wiki '''Simulant''' is a cross-platform general-purpose game engine written in C++. It is designed with portability in mind, using minimal dependencies and targetting C++11 (rather than more modern versions of the language). The aim of Simulant is to create an easy-to-use game engine to allow building homebrew for older games consoles, as well as creating a great developer-experience on modern platforms. === Features === * Easy to use API, and getting simpler all the time! * Flexible rendering pipeline * Complex material scripting format * Loading of .obj models and the X-Wing vs Tie Fighter .opt format * Loading of MD2 animated models * Loading of Q2 BSP files (needs work) * Loading of heightmap terrains from image files * Advanced spatial hash partitioning and culling * Loading of JPG, PNG, TGA, WAL, PCX images and more! * Shortcut functions for loading 2D sprites, 2D backgrounds and 3D skyboxes * Simple scene graph functions * UI widgets (Button, Label, Progress Bar) * Basic rigid body physics using the Bounce library * Procedural functions for generating spheres, cubes, capsules, circles and rectangles * Functions for creating lights, multiple viewports and cameras === Official Repository === https://gitlab.com/simulant/simulant {{DCWiki:Stub}} 66a96aa908f58b6b218beb4cc028e0f120fdc9d9 399 398 2020-01-11T12:54:53Z Unknown user 0 wikitext text/x-wiki '''[https://simulant-engine.appspot.com Simulant]''' is a cross-platform general-purpose game engine written in C++. It is designed with portability in mind, using minimal dependencies and targetting C++11 (rather than more modern versions of the language). The aim of Simulant is to create an easy-to-use game engine to allow building homebrew for older games consoles, as well as creating a great developer-experience on modern platforms. === Features === * Easy to use API, and getting simpler all the time! * Flexible rendering pipeline * Complex material scripting format * Loading of .obj models and the X-Wing vs Tie Fighter .opt format * Loading of MD2 animated models * Loading of Q2 BSP files (needs work) * Loading of heightmap terrains from image files * Advanced spatial hash partitioning and culling * Loading of JPG, PNG, TGA, WAL, PCX images and more! * Shortcut functions for loading 2D sprites, 2D backgrounds and 3D skyboxes * Simple scene graph functions * UI widgets (Button, Label, Progress Bar) * Basic rigid body physics using the Bounce library * Procedural functions for generating spheres, cubes, capsules, circles and rectangles * Functions for creating lights, multiple viewports and cameras === Official Repository === https://gitlab.com/simulant/simulant {{DCWiki:Stub}} bfc61453b85714cfd8a97d91a95b2010ae7d0c63 User:Freakdave 2 133 400 2020-01-11T13:29:03Z Unknown user 0 Created page with "=== Past projects === * Extended [http://surreal64ce.wikidot.com/info:info Surreal64] (N64 emulator on XBOX) * Ported [https://www.emuxtras.net/forum/viewtopic.php?f=189&t=354..." wikitext text/x-wiki === Past projects === * Extended [http://surreal64ce.wikidot.com/info:info Surreal64] (N64 emulator on XBOX) * Ported [https://www.emuxtras.net/forum/viewtopic.php?f=189&t=3543 Yabause CE] (Sega Saturn emulator) to XBOX * Ported countless open-source SDL games (e.g. Zelda - Oni Link Begins, Jump 'n' BumpX, etc..) to XBOX * Created Project Dash (GUI frontend used in Yabause CE and partly 3dox) * Ported [http://svn.huntsvegas.org/listing.php?repname=FakeGLx FakeGLx] and [http://svn.huntsvegas.org/listing.php?repname=xGLDirect xGLDirect] (Direct3D -> OpenGL wrapper) to XBOX * Ported [http://svn.huntsvegas.org/listing.php?repname=IrrlichtX IrrlichtX] (graphics engine) to XBOX * Contributed various speed up fixes to the XBOX port of the Playstation 1 emulator [https://github.com/freakdave/PCSX-ReloadedX-Stable PCSX-ReloadedX] === Current projects === * Create a small 3D homebrew demo for the Dreamcast with [[Simulant]] * Contribute code and bug fixes to [[Simulant]] 8bd14d7556a873c715509a6efc8cb24dcbbe1b1d 401 400 2020-01-11T13:31:17Z Unknown user 0 wikitext text/x-wiki === Past projects === * Extended [http://surreal64ce.wikidot.com/info:info Surreal64] (N64 emulator on XBOX) * Ported [https://www.emuxtras.net/forum/viewtopic.php?f=189&t=3543 Yabause CE] (Sega Saturn emulator) to XBOX * Ported countless open-source SDL games (e.g. Zelda - Oni Link Begins, Jump 'n' BumpX, etc..) to XBOX * Created Project Dash ([https://xbins.org/nfo.php?file=xboxnfo2181.nfo GUI frontend used in Yabause CE and partly 3dox]) * Ported [http://svn.huntsvegas.org/listing.php?repname=FakeGLx FakeGLx] and [http://svn.huntsvegas.org/listing.php?repname=xGLDirect xGLDirect] (Direct3D -> OpenGL wrapper) to XBOX * Ported [http://svn.huntsvegas.org/listing.php?repname=IrrlichtX IrrlichtX] (graphics engine) to XBOX * Contributed various speed up fixes to the XBOX port of the Playstation 1 emulator [https://github.com/freakdave/PCSX-ReloadedX-Stable PCSX-ReloadedX] === Current projects === * Create a small 3D homebrew demo for the Dreamcast with [[Simulant]] * Contribute code and bug fixes to [[Simulant]] ef87a549dab0a1d15e258b82fc706f56962374f9 402 401 2020-01-11T15:49:16Z Unknown user 0 wikitext text/x-wiki === Past projects === * Extended [http://surreal64ce.wikidot.com/info:info Surreal64] (N64 emulator on XBOX) * Ported [https://www.emuxtras.net/forum/viewtopic.php?f=189&t=3543 Yabause CE] (Sega Saturn emulator) to XBOX * Ported countless open-source [https://web.archive.org/web/20121014020252/http://freakdave.xbox-scene.com/ SDL games] (e.g. Zelda - Oni Link Begins, Jump 'n' BumpX, etc..) to XBOX * Created Project Dash ([https://xbins.org/nfo.php?file=xboxnfo2181.nfo GUI frontend used in Yabause CE and partly 3dox]) * Ported [http://svn.huntsvegas.org/listing.php?repname=FakeGLx FakeGLx] and [http://svn.huntsvegas.org/listing.php?repname=xGLDirect xGLDirect] (Direct3D -> OpenGL wrapper) to XBOX * Ported [http://svn.huntsvegas.org/listing.php?repname=IrrlichtX IrrlichtX] (graphics engine) to XBOX * Contributed various speed up fixes to the XBOX port of the Playstation 1 emulator [https://github.com/freakdave/PCSX-ReloadedX-Stable PCSX-ReloadedX] === Current projects === * Create a small 3D homebrew demo for the Dreamcast with [[Simulant]] * Contribute code and bug fixes to [[Simulant]] 40363ec099209ffa8b3b5ba0713b39882187463d Emulators on Dreamcast 0 108 403 307 2020-01-11T16:09:28Z Unknown user 0 /* SNK NeoGeo CD */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 0b037693f1d60f382167f458b6494d31f49d9bbc DREAMNEOCD 0 134 404 2020-01-11T16:11:13Z Unknown user 0 Created page with "Dream neo cd is a based of my old port neogeo cd sdl You can find the src at https://github.com/ianmicheal/Dreamneo-cd" wikitext text/x-wiki Dream neo cd is a based of my old port neogeo cd sdl You can find the src at https://github.com/ianmicheal/Dreamneo-cd 3e5fd971a6c9c69bc0155f42131d76157799cd1e Engine & Library 0 27 405 323 2020-01-11T16:20:21Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake]() - Quake engine by Ian Micheal *[Openbor beats of rage] * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 12054e9b8879037ed4a810da1e5866a649569ef6 406 405 2020-01-11T16:35:44Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal *[Openbor beats of rage] * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 1da868be479ffd1bfdfc4ba94278aa6db5917dd5 414 406 2020-01-11T18:12:54Z Unknown user 0 Added ESTk to list of engines wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [Elysian Shadows Toolkit](http://elysianshadows.com) - General-purpose Toolkit and Engine being actively developed to power Elysian Shadows (currently closed-source, but it will be released with the game). * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal *[Openbor beats of rage] * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 3a4f16d93341a798649a8f1058010c1ba98038e9 Dreammidi 0 135 407 2020-01-11T17:34:11Z Unknown user 0 Created page with " Dreammidi v1.0 /////////////////////////////////////////////////////////////////////////////////////////////// PROLOG ------ Welcome ive been working On a midi media player..." wikitext text/x-wiki Dreammidi v1.0 /////////////////////////////////////////////////////////////////////////////////////////////// PROLOG ------ Welcome ive been working On a midi media player for some time. This new version has c64 theme is 44kz stereo and plays more formats and is now stable /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// MEATY INFO ------ This will play midi,ogg,wav,mod,aiff,XM,IT,s3m,vox,699 Its main job is to let you play midi files. SO midi's on your Dreamcast. Welecome to Dream Midi this player plays midi files in 44kh Stereo. and the Other formats as well. Old dev log and thanks It was programed by me this is not a port. I had coaching from a few other coders. In order! Bluecrab,BlackAura,Phantom. These people provide tips and help.When /////////////////////////////////////////////////////////////////////////////////////////////// 6bd75ae43d1666686bc2993afd0a4e1c2852252e 409 407 2020-01-11T17:40:14Z Unknown user 0 Replaced content with "https://github.com/ianmicheal/DREAM-MIDI Dreammidi v1.0" wikitext text/x-wiki https://github.com/ianmicheal/DREAM-MIDI Dreammidi v1.0 9b0ede4bff4480e51c004423ad2e095eea55b28c Media players 0 67 408 239 2020-01-11T17:37:45Z Unknown user 0 /* Audio players */ wikitext text/x-wiki == Commercial media players == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Blaze MP3]] | MP3 Player | |- | [[Pelican MP3]] | | |- | [[Dream VCD Player]] | | |} == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * [[DreamAMP]] * [[JPamp3]] * [[ToEleven]] * [[SIDPlay]] *[[Dreammidi]]* [radQuake](https://github.com/ianmicheal/DREAM-MIDI) - by Ian Micheal === Image viewers === * [[D.I.S.S.]] === Video players === * [[DC Movie Player]] * [[DCDivX]] * [[GypPlay]] * [[uDCDivX]] * [[VC/DC]] 31aaabe8586e0de52218b8c2698f7f69bb3ae881 410 408 2020-01-11T17:40:43Z Unknown user 0 /* Audio players */ wikitext text/x-wiki == Commercial media players == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Blaze MP3]] | MP3 Player | |- | [[Pelican MP3]] | | |- | [[Dream VCD Player]] | | |} == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * [[DreamAMP]] * [[JPamp3]] * [[ToEleven]] * [[SIDPlay]] *[[Dreammidi]]*(https://github.com/ianmicheal/DREAM-MIDI) - by Ian Micheal === Image viewers === * [[D.I.S.S.]] === Video players === * [[DC Movie Player]] * [[DCDivX]] * [[GypPlay]] * [[uDCDivX]] * [[VC/DC]] fc85940688660aadf30d4049225014b26ebb0828 411 410 2020-01-11T17:41:21Z Unknown user 0 /* Audio players */ wikitext text/x-wiki == Commercial media players == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Blaze MP3]] | MP3 Player | |- | [[Pelican MP3]] | | |- | [[Dream VCD Player]] | | |} == Homebrew media players == === Audio players === * [[DCMP3]] * [[DCPlaya]] * [[DreamAMP]] * [[JPamp3]] * [[ToEleven]] * [[SIDPlay]] *[[Dreammidi]] === Image viewers === * [[D.I.S.S.]] === Video players === * [[DC Movie Player]] * [[DCDivX]] * [[GypPlay]] * [[uDCDivX]] * [[VC/DC]] 4c305ba474a634e68dc87cbcc7936661ed550436 File:Vmu Manual.pdf 6 136 412 2020-01-11T18:03:42Z Unknown user 0 Official VMU manual wikitext text/x-wiki == Summary == Official VMU manual 7de3f2f37f40bd0f27160fd213176f5f6f8d5022 VMU 0 137 413 2020-01-11T18:04:27Z Unknown user 0 Created page with "[[:File:Vmu_Manual.pdf|VMU manual]] {{DCWiki:Stub}}" wikitext text/x-wiki [[:File:Vmu_Manual.pdf|VMU manual]] {{DCWiki:Stub}} 8aab642cb1dae57caceb176f73fc8313af81c125 Indie games 0 13 415 277 2020-01-11T18:20:11Z Unknown user 0 added Elysian Shadows wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft || |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} 00390cbcedb76810f96a9282f57bb9978176f614 416 415 2020-01-11T18:21:28Z Unknown user 0 wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} 50369753631b7e0eb74d2cc2273761872e579587 BIOS 0 78 417 280 2020-01-11T18:23:28Z Unknown user 0 wikitext text/x-wiki The Sega Dreamcast BIOS has several known revisions: * v1.004 or MPR-21068, found in Japanese consoles only * v1.01c or MPR-21871, found in PAL consoles * v1.01d or MPR-21931 or MPR-21933, found in consoles worldwide ** The [[Treamcast]] console uses a hacked version of this firmware with Chinese support. * v1.022 or MPR-23588, found in U.S. and Japanese consoles ** Consoles with this revision BIOS have [[MIL-CD]] booting disabled. {{DCWiki:Stub}} {| class="wikitable" |+Known BIOS images |- ! Version ! Label ! Regions ! HW Revisions ! Notes ! CRC32 ! MD5 ! SHA1 |- |v1.004 |MPR-21068 |Japan |va0 |No support for region flags in flash, hardcoded to Japan |5454841f |37c921eb47532cae8fb70e5d987ce91c |1ea132c0fbbf07ef76789eadc07908045c089bd6 |- |v1.01c |MPR-21871 |PAL | | |2f551bc5 |6679bc5f3006b5bdb019b2781f537373 |1ede8d5be49116a4c6f3fe0961175469537a0434 |- |v1.01d |MPR-21931, MPR-21933 |Japan, U.S., PAL |va1 | |89f2b1a1 |e10c53c2f8b90bab96ead2d368858623 |8951d1bb219ab2ff8583033d2119c899cc81f18c |- |v1.01d (hack) | ??? |Japan |va1 |Treamcast console BIOS, menu translated to Chinese |cff88d0d |583f96b3e255ed405abc5bdbad8635c0 |e3f84705b183ffded0a349ac7f2ab00be2ab74ee |- |v1.022 |MPR-23588 |Japan, U.S. |va2 |MIL-CD loading support removed |786168f9 |f2cd29d09f3e29984bcea22ab2e006fe |ba8bbb90fdb29525f24f17055dc2c7b2d7674437 |} 8fc4468ff257671cf16564e81950b5e6d072d1eb 418 417 2020-01-11T18:24:37Z Unknown user 0 wikitext text/x-wiki The Sega Dreamcast BIOS has several known revisions: {| class="wikitable" |+Known BIOS images |- ! Version ! Label ! Regions ! HW Revisions ! Notes ! CRC32 ! MD5 ! SHA1 |- |v1.004 |MPR-21068 |Japan |va0 |No support for region flags in flash, hardcoded to Japan |5454841f |37c921eb47532cae8fb70e5d987ce91c |1ea132c0fbbf07ef76789eadc07908045c089bd6 |- |v1.01c |MPR-21871 |PAL | | |2f551bc5 |6679bc5f3006b5bdb019b2781f537373 |1ede8d5be49116a4c6f3fe0961175469537a0434 |- |v1.01d |MPR-21931, MPR-21933 |Japan, U.S., PAL |va1 | |89f2b1a1 |e10c53c2f8b90bab96ead2d368858623 |8951d1bb219ab2ff8583033d2119c899cc81f18c |- |v1.01d (hack) | ??? |Japan |va1 |Treamcast console BIOS, menu translated to Chinese |cff88d0d |583f96b3e255ed405abc5bdbad8635c0 |e3f84705b183ffded0a349ac7f2ab00be2ab74ee |- |v1.022 |MPR-23588 |Japan, U.S. |va2 |MIL-CD loading support removed |786168f9 |f2cd29d09f3e29984bcea22ab2e006fe |ba8bbb90fdb29525f24f17055dc2c7b2d7674437 |} {{DCWiki:Stub}} 8c8b7b8725e77f3654e040d0748960a94dc58e82 452 418 2020-01-12T06:36:15Z Unknown user 0 wikitext text/x-wiki The Sega Dreamcast BIOS has several known revisions: {| class="wikitable" |+Known BIOS images |- ! Version ! Label ! Regions ! HW Revisions ! Notes ! CRC32 ! MD5 ! SHA1 |- |v1.004 |MPR-21068 |Japan |va0 |No support for region flags in flash, hardcoded to Japan |5454841f |37c921eb47532cae8fb70e5d987ce91c |1ea132c0fbbf07ef76789eadc07908045c089bd6 |- |v1.01c |MPR-21871 |PAL | | |2f551bc5 |6679bc5f3006b5bdb019b2781f537373 |1ede8d5be49116a4c6f3fe0961175469537a0434 |- |v1.01d |MPR-21931, MPR-21933 |Japan, U.S., PAL |va1 | |89f2b1a1 |e10c53c2f8b90bab96ead2d368858623 |8951d1bb219ab2ff8583033d2119c899cc81f18c |- |v1.01d (hack) | ??? |Japan |va1 |[[Treamcast]] console BIOS, menu translated to Chinese |cff88d0d |583f96b3e255ed405abc5bdbad8635c0 |e3f84705b183ffded0a349ac7f2ab00be2ab74ee |- |v1.022 |MPR-23588 |Japan, U.S. |va2 |MIL-CD loading support removed |786168f9 |f2cd29d09f3e29984bcea22ab2e006fe |ba8bbb90fdb29525f24f17055dc2c7b2d7674437 |} {{DCWiki:Stub}} 5178c8622d739f18e4931945829e4c8f520e8b22 Engine & Library 0 27 419 414 2020-01-11T18:25:07Z Unknown user 0 Added libGyro wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadow.com) - Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [Elysian Shadows Toolkit](http://elysianshadows.com) - General-purpose Toolkit and Engine being actively developed to power Elysian Shadows (currently closed-source, but it will be released with the game). * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal *[Openbor beats of rage] * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 7b75989dbbbee5ad9198fb9b359879cdfbebf000 431 419 2020-01-11T22:46:12Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadow.com) - Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [Elysian Shadows Toolkit](http://elysianshadows.com) - General-purpose Toolkit and Engine being actively developed to power Elysian Shadows (currently closed-source, but it will be released with the game). * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal *[unofficial Dreambor Openbor beats of rage](https://github.com/ianmicheal/Dreambor6.0) My update of the engine to allow 16 and 32 bit colour rending and use less ram -by Ian micheal * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) fe11d9e6eb8ac2fe596cbd6203996fd12190cb8b 439 431 2020-01-12T03:46:34Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal *[unofficial Dreambor Openbor beats of rage](https://github.com/ianmicheal/Dreambor6.0) My update of the engine to allow 16 and 32 bit colour rending and use less ram -by Ian micheal * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) f22072871bb9aecbb42e931df3e6b06b02935417 441 439 2020-01-12T04:16:48Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [LibFatFS](https://github.com/andressbarajas/libfatfs) - A FAT16 and FAT32 lib to use with the SD card adapter. * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) f7c1636bb370629815aafae2ab9e037375b562b2 DCWiki:Hardware 4 82 420 245 2020-01-11T18:49:00Z Unknown user 0 /* Hardware */ wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCHDMI]], [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} 91a8761bf7b67a90a51ad1e5b8e6461af9ce268f Indie games 0 13 421 416 2020-01-11T19:52:26Z Unknown user 0 wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Rizzo's Island]] || 3D platformer || |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || |- | [[Summoning Signals]] || a strange game || https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} {{DCWiki:Stub}} 5b028a2da110abcf157b3ba3655edf3e92dc14dd 424 421 2020-01-11T20:43:26Z Unknown user 0 wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Release Date !! Website |- | [[Rizzo's Island]] | 3D platformer | ?? | |- | [[Swirling Blades: Desert Thunder]] | | Kazade's choplifter remix ;) | | | |- | [[Summoning Signals]] | a strange game | Late 2020 | https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] | "Next-Gen" 2D/3D JRPG | | https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} {{DCWiki:Stub}} eaa0ff6f30df96408494101f70d0b366f1f64e5b 425 424 2020-01-11T20:45:46Z Unknown user 0 /* Active Development */ wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Rizzo's Island]] | 3D platformer | | |- | [[Swirling Blades: Desert Thunder]] | Kazade's choplifter remix ;) | | |- | [[Summoning Signals]] | a strange game | Late 2020 | https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] | "Next-Gen" 2D/3D JRPG | | https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} {{DCWiki:Stub}} 274190a94012e64735fcccc31b7d55ff198e1df7 438 425 2020-01-12T03:39:28Z Unknown user 0 wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Rizzo's Island]] | 3D platformer | | |- | [[Swirling Blades: Desert Thunder]] | Kazade's choplifter remix ;) | | |- | [[Summoning Signals]] | a strange game | Late 2020 | https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] | "Next-Gen" 2D/3D JRPG | TBD | https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[Feet of Fury]] || Rhythm game || |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |} {{DCWiki:Stub}} c9127d420fae0a4f439f51f4b3c9484fea501f0f MediaWiki:Sidebar 8 10 422 248 2020-01-11T19:58:42Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|Dreamcast Wiki ** forums-url|DCEmulation forums ** simulant-discord-url|Simulant Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES fc3c41cb25023a0c50c2d256614e307d122ab760 423 422 2020-01-11T19:59:33Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|Dreamcast Wiki ** forums-url|Message Board ** simulant-discord-url|Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES 75e11e7427a99da1eca022b8908ebf8dacd71e7a Talk:Engine & Library 1 138 426 2020-01-11T20:52:50Z Unknown user 0 Created page with "Not sure if this page should include engines/libs that are not available for testing/using. (LibGyro/ESTK)" wikitext text/x-wiki Not sure if this page should include engines/libs that are not available for testing/using. (LibGyro/ESTK) cd79eca582d9991cd75b4ca56842f12822efb3d5 427 426 2020-01-11T20:53:07Z Unknown user 0 wikitext text/x-wiki Not sure if this page should include engines/libs that are not available for testing/using. (LibGyro/ESTK) --[[User:Magnes|Magnes]] ([[User talk:Magnes|talk]]) 12:53, 11 January 2020 (PST) 6feb533b25fcc7df2625dcbeeac326605c3701d0 440 427 2020-01-12T03:47:32Z Unknown user 0 wikitext text/x-wiki Not sure if this page should include engines/libs that are not available for testing/using. (LibGyro/ESTK) --[[User:Magnes|Magnes]] ([[User talk:Magnes|talk]]) 12:53, 11 January 2020 (PST) * I certainly understand what you mean. For now, I've pushed LibGyro/ESTK to the bottom of their respective sections and tagged them as unreleased/in-development. Thoughts, anyone? --[[User:Darc|Darc]] ([[User talk:Darc|talk]]) 19:47, 11 January 2020 (PST) c7e50105f20dfefc43e97d187758d3c4691e2100 Romdisk Swapping 0 125 428 362 2020-01-11T21:14:28Z Unknown user 0 wikitext text/x-wiki Author: Lerabot/Magnes = Introduction = When I started adding things to the ROM disk, I didn't realize that my 10MB+ .elf file would be problematic (i.e. not load) on the Dreamcast. Also it's been mentioned in a forum topic that loading a romdisk instead of multiple files would be faster. **Need source** I also think that it could be a neat way to handle/manage your memory altogether. * 2020 edit : Removed the GZ compression as it seemed to cause problem with filename longer than a certain length (16 IIRC?) * = Guide = == Organize your assets == Organize the content or your romdisk in multiple folders: ``` /level1 /level2 /level3 ``` == Convert to romdisk == In your Makefile, duplicate the usual romdisk generation command but change the romdisk name and directory. This is the usual romdisk command, you can still keep this $(KOS_GENROMFS) -f romdisk.img -d path/to/romdisk -v This is your new romdisk, replace the romdisk_name and romdisk_folder with what you want. $(KOS_GENROMFS) -f romdisk_name.img -d path/to/romdisk_folder -v If I'm using the example from earlier, I could make a "level1" romdisk this way $(KOS_GENROMFS) -f level1.img -d path/to/level -v == Step 3 == In your code you'll need a way to load those new romdisks, we'll use this code snippet by ''BlackAura''. For more info, check this topic [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=68795&hilit=romdisk+feet+of+fury] #include <kos.h> #include <zlib/zlib.h> // Thanks BlackAura ;) int mount_romdisk(char *filename, char *mountpoint) { void *buffer; int length = zlib_getlength(filename); // Check failure if(length == 0) return 0; // Allocate memory, read file buffer = malloc(length); gzread(file, buffer, length); gzclose(file); // Mount fs_romdisk_mount(mountpoint, buffer, 1); return 1; } ** It is important that your mount point start with a '/' -> "/level1" and not "level1" ** You can now unload the romdisk using: fs_romdisk_unmount(mountpoint); = Usage with a Broadband adapter or dc-ipload = In order to use these new romdisk, you need to enable ''/pc'' redirection in your ''dc-tool'', update your ''dc-tool'' command to use ''-c'': dc-tool-ip -t dreamcast -c /path/to/project -x program_name.elf You can now use the function below to access files in the ''/rom'' folder: mount_romdisk("/pc/romdisk_name.img.gz", "/rom"); Keep in mind that you'll have to switch ''/pc/'' to ''/cd/'' when you burn this to a CD. cb53255ff2144dea0a9a2f4e82934d5a6728723e 429 428 2020-01-11T21:16:34Z Unknown user 0 wikitext text/x-wiki Author: Lerabot/Magnes = Introduction = When I started adding things to the ROM disk, I didn't realize that my 10MB+ .elf file would be problematic (i.e. not load) on the Dreamcast. Also it's been mentioned in a forum topic that loading a romdisk instead of multiple files would be faster. **Need source** I also think that it could be a neat way to handle/manage your memory altogether. ''2020 edit : Removed the GZ compression as it seemed to cause problem with filename longer than a certain length (16 IIRC?)'' = Guide = == Organize your assets == Organize the content or your romdisk in multiple folders: /level1 /level2 /level3 == Convert to romdisk == In your Makefile, duplicate the usual romdisk generation command but change the romdisk name and directory. This is the usual romdisk command, you can still keep this $(KOS_GENROMFS) -f romdisk.img -d path/to/romdisk -v This is your new romdisk, replace the romdisk_name and romdisk_folder with what you want. $(KOS_GENROMFS) -f romdisk_name.img -d path/to/romdisk_folder -v If I'm using the example from earlier, I could make a "level1" romdisk this way $(KOS_GENROMFS) -f level1.img -d path/to/level -v == Step 3 == In your code you'll need a way to load those new romdisks, we'll use this code snippet by ''BlackAura''. For more info, check this topic [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=68795&hilit=romdisk+feet+of+fury] #include <kos.h> #include <zlib/zlib.h> // Thanks BlackAura ;) int mount_romdisk(char *filename, char *mountpoint) { void *buffer; int length = zlib_getlength(filename); // Check failure if(length == 0) return 0; // Allocate memory, read file buffer = malloc(length); gzread(file, buffer, length); gzclose(file); // Mount fs_romdisk_mount(mountpoint, buffer, 1); return 1; } ''' It is important that your mount point start with a '/' -> "/level1" and not "level1" ''' You can now unload the romdisk using: fs_romdisk_unmount(mountpoint); = Usage with a Broadband adapter or dc-ipload = In order to use these new romdisk, you need to enable ''/pc'' redirection in your ''dc-tool'', update your ''dc-tool'' command to use ''-c'': dc-tool-ip -t dreamcast -c /path/to/project -x program_name.elf You can now use the function below to access files in the ''/rom'' folder: mount_romdisk("/pc/romdisk_name.img.gz", "/rom"); Keep in mind that you'll have to switch ''/pc/'' to ''/cd/'' when you burn this to a CD. 57036d6ee18d226e15b5bc3b00d82d80f2455732 430 429 2020-01-11T21:21:01Z Unknown user 0 wikitext text/x-wiki Author: Lerabot/Magnes = Introduction = When I started adding things to the ROM disk, I didn't realize that my 10MB+ .elf file would be problematic (i.e. not load) on the Dreamcast. Also it's been mentioned in a forum topic that loading a romdisk instead of multiple files would be faster. **Need source** I also think that it could be a neat way to handle/manage your memory altogether. ''2020 edit : Removed the GZ compression as it seemed to cause problem with filename longer than a certain length (16 IIRC?)'' = Guide = == Organize your assets == Organize the content or your romdisk in multiple folders: /level1 /level2 /level3 == Convert to romdisk == In your Makefile, duplicate the usual romdisk generation command but change the romdisk name and directory. This is the usual romdisk command, you can still keep this $(KOS_GENROMFS) -f romdisk.img -d path/to/romdisk -v This is your new romdisk, replace the romdisk_name and romdisk_folder with what you want. $(KOS_GENROMFS) -f romdisk_name.img -d path/to/romdisk_folder -v If I'm using the example from earlier, I could make a "level1" romdisk this way $(KOS_GENROMFS) -f level1.img -d path/to/level -v == Using your romdisk == In your code you'll need a way to load those new romdisks, we'll use this code snippet by ''BlackAura''. For more info, check this topic [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=68795&hilit=romdisk+feet+of+fury] #include <kos.h> #include <zlib/zlib.h> // Thanks BlackAura ;) int mount_romdisk(char *filename, char *mountpoint) { void *buffer; int length = zlib_getlength(filename); // Check failure if(length == 0) return 0; // Allocate memory, read file buffer = malloc(length); gzread(file, buffer, length); gzclose(file); // Mount fs_romdisk_mount(mountpoint, buffer, 1); return 1; } ''' It is important that your mount point start with a '/' -> "/level1" and not "level1" ''' You can now load files that are located at "/level1". Example "/level1/spritesheet.png" You can unload the romdisk using: fs_romdisk_unmount(mountpoint); = Usage with a Broadband adapter or dc-ipload = In order to use these new romdisk, you need to enable ''/pc'' redirection in your ''dc-tool'', update your ''dc-tool'' command to use ''-c'': dc-tool-ip -t dreamcast -c /path/to/project -x program_name.elf You can now use the function below to access files in the ''/rd'' folder: mount_romdisk("/pc/romdisk_name.img", "/rd"); Keep in mind that you'll have to switch ''/pc/'' to ''/cd/'' when you burn this to a CD. f0aee5a75ce9b01a378ad08a6c96abfe92b33925 SDRip 0 139 432 2020-01-12T03:19:32Z Unknown user 0 Created page with "{{Release |Page name=SDRip |titlescreen=sdrip-1.png |status=Released |releasedby=jj1odm |name=SDRop |genre=Tool, Utility |release_date= Feb 21, 2018 |unreleased=No }} {{Downlo..." wikitext text/x-wiki {{Release |Page name=SDRip |titlescreen=sdrip-1.png |status=Released |releasedby=jj1odm |name=SDRop |genre=Tool, Utility |release_date= Feb 21, 2018 |unreleased=No }} {{Download |file=Dcsdrip11.zip }} == Description == '''Original Release Announcement''' Dreamcast SD Rip ver1.0 ... (DATA track: raw binary / for file division / for Bad CRC Dreamcast) usage: Please connect the controller with port A. The speed has about 650KBytes / sec.Time to ripping GD-ROM is about 35 minutes in total.SD == Screenshots == <gallery mode=nolines heights=168 widths=240> sdrip-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s to SD card == Source == [https://jj1odm.sizious.com/dcserial_ft232bm.html#dcsdload https://jj1odm.sizious.com/dcserial_ft232bm.html#dcsdload] __NOTOC__ 8b1f1704f7c8a51670e0bb1aace3985f4aa26f26 434 432 2020-01-12T03:20:27Z Unknown user 0 /* Description */ wikitext text/x-wiki {{Release |Page name=SDRip |titlescreen=sdrip-1.png |status=Released |releasedby=jj1odm |name=SDRop |genre=Tool, Utility |release_date= Feb 21, 2018 |unreleased=No }} {{Download |file=Dcsdrip11.zip }} == Description == '''Original Release Announcement''' Dreamcast SD Rip ver1.0 ... (DATA track: raw binary / for file division / for Bad CRC Dreamcast) usage: Please connect the controller with port A. The speed has about 650KBytes / sec.Time to ripping GD-ROM is about 35 minutes in total.SD == Screenshots == <gallery mode=nolines heights=168 widths=240> sdrip-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s to SD card == Source == [https://jj1odm.sizious.com/dcserial_ft232bm.html#dcsdload https://jj1odm.sizious.com/dcserial_ft232bm.html#dcsdload] __NOTOC__ cb0c1f70b8eae4f9324fad4c8b90904e65963b1d 435 434 2020-01-12T03:20:40Z Unknown user 0 /* Description */ wikitext text/x-wiki {{Release |Page name=SDRip |titlescreen=sdrip-1.png |status=Released |releasedby=jj1odm |name=SDRop |genre=Tool, Utility |release_date= Feb 21, 2018 |unreleased=No }} {{Download |file=Dcsdrip11.zip }} == Description == '''Original Release Announcement''' Dreamcast SD Rip ver1.0 ... (DATA track: raw binary / for file division / for Bad CRC Dreamcast) usage: Please connect the controller with port A. The speed has about 650KBytes / sec.Time to ripping GD-ROM is about 35 minutes in total.SD == Screenshots == <gallery mode=nolines heights=168 widths=240> sdrip-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s to SD card == Source == [https://jj1odm.sizious.com/dcserial_ft232bm.html#dcsdload https://jj1odm.sizious.com/dcserial_ft232bm.html#dcsdload] __NOTOC__ edf8956a0551237629bc572b69453aec52be1cd3 File:Sdrip-1.png 6 140 433 2020-01-12T03:19:56Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Httpd-ack-1.png 6 141 436 2020-01-12T03:26:25Z Unknown user 0 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Httpd-ack 0 142 437 2020-01-12T03:26:59Z Unknown user 0 Created page with "{{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 20..." wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} == Description == '''Original Release Announcement''' dreamcast gd-rom dumper, requires bba === Usage === [https://www.gotwalls.com/files/httpd-ack.txt https://www.gotwalls.com/files/httpd-ack.txt] == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s using a [[BBA]] over the network to a PC == Source == [https://www.gotwalls.com/ https://www.gotwalls.com/] __NOTOC__ e70d65272ba47fc39a9d34e534b8982d11d56bdf 457 437 2020-01-12T06:55:25Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} == Description == '''Original Release Announcement''' dreamcast gd-rom dumper, requires bba === Usage === [https://www.gotwalls.com/files/httpd-ack.txt https://www.gotwalls.com/files/httpd-ack.txt] == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s using a [[BBA]] over the network to a PC == Source == [https://www.gotwalls.com/ https://www.gotwalls.com/] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} 3440a86e013fefa3629e92aa202836e34e286192 Talk:Scrambling 1 143 442 2020-01-12T04:25:19Z Unknown user 0 Created page with "are you a scramble, descramble kinda person or more a forward/backward scramble kinda person? --~~~~" wikitext text/x-wiki are you a scramble, descramble kinda person or more a forward/backward scramble kinda person? --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 20:25, 11 January 2020 (PST) 2a999d7066147b66fea94dce4271b948b3f11f9c 445 442 2020-01-12T04:41:47Z Unknown user 0 wikitext text/x-wiki are you a scramble, descramble kinda person or more a forward/backward scramble kinda person? --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 20:25, 11 January 2020 (PST) I take my scrambling the way it's been given to me. --[[User:Magnes|Magnes]] ([[User talk:Magnes|talk]]) 20:41, 11 January 2020 (PST) 5fedb37469c8b66abc89a0f1fbd44c4a28d893fc Tools and Utilities 0 131 443 396 2020-01-12T04:33:43Z Unknown user 0 wikitext text/x-wiki This article will list various tools and utilities for Dreamcast development and game hacking. == CD utilities == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[dcdis]] || || |- | [[mkisofs]] || Bundle your project directory into a .iso || |- | [[cdi4dc]] || Create bootable .CDI files || |- | [[img4dc]] || Updated version of cdi4dc || |} == Texture converter == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[Texconv]] || Convert your texture to the .dtex format || |- | [[Crayon Utilities]] || VMU and RGBA888 image conversion || [https://github.com/Protofall/Crayon-Utilities Github] |} {{DCWiki:Stub}} a8e96bbfb53bb73d765dec6e07b8914e1a55ccf8 462 443 2020-01-12T16:04:51Z Unknown user 0 Added link to TexConv project, because Tvspelsfreak was my old mentor and homeboy. wikitext text/x-wiki This article will list various tools and utilities for Dreamcast development and game hacking. == CD utilities == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[dcdis]] || || |- | [[mkisofs]] || Bundle your project directory into a .iso || |- | [[cdi4dc]] || Create bootable .CDI files || |- | [[img4dc]] || Updated version of cdi4dc || |} == Texture converter == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[Texconv]] || Convert your texture to the .dtex format || [https://github.com/tvspelsfreak/texconv Github] |- | [[Crayon Utilities]] || VMU and RGBA888 image conversion || [https://github.com/Protofall/Crayon-Utilities Github] |} {{DCWiki:Stub}} 8f569ac28801fb264605cdb5d547b0b2cee31b6b DCWiki:Software 4 81 444 395 2020-01-12T04:35:53Z Unknown user 0 wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 7c97ef0f7364eb97d72e22d2fea2a6fc7af09701 453 444 2020-01-12T06:37:11Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 17202b0113191b87cb6522770b09b2f5ffd5a8ec Memory map 0 105 446 300 2020-01-12T05:00:56Z Unknown user 0 /* Physical address format */ wikitext text/x-wiki = Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming: Memory Map, Marcus Comstedt</ref> When the built-in MMU is active, the mapping between logical and physical address is basically left up to the programmer (see the SH4 Hardware Manual for details), however the normal mode of operation in the Dreamcast is to have the MMU disabled, in which the mapping is fixed as described below. = Logical address format= When the MMU is disabled, the 32-bit logical addresses have the following format: {| class=wikitable ! 31 ! 30 ! 29 ! 28 ... 0 |- | P | ALT | NC | Physical address |} === Modifier Bits === In addition to the physical address, the following modifier bits are used: {|class=wikitable ! P | Privileged Access | Addresses with the P bit set can only be accessed when the CPU is running in privileged mode, that is when the MD bit in the status register is set. An exception to this is the Store Queue though. P inhibits the MMU, and enables the ALT and NC bits. If P is not set, ALT and NC are ignored. |- ! ALT | Alternate Address Space | Setting this bit gives an alternate mapping of the physical address bits. If NC is also set, the builtin CPU I/O registers are selected. If NC is not set, MMU translation is selected (if MMU is enabled) even though P is set. |- ! NC | Not Cacheable | Setting this bit circumvents the data cache, which is useful for accessing external hardware registers. |} === Modifier Bit Combinations === The following table shows the possible combinations of the modifier bits: {|class=wikitable !P !ALT !NC !Address range !Description !Area name |- |0 |X |X |0x00000000-0x7FFFFFFF (Physical address space repeats 4 times) |Address translation through MMU (if enabled). Can be accessed in both User and Privileged mode. |U0/P0 |- |1 |0 |0 |0x80000000-0x9FFFFFFF |Privileged mode only. |P1 |- |1 |0 |1 |0xA0000000-0xBFFFFFFF |Privileged mode only, no cache. |P2 |- |1 |1 |0 |0xC0000000-0xDFFFFFFF |Privileged mode only. Address translation through MMU (if enabled). |P3 |- |1 |1 |1 |0xE0000000-0xFFFFFFFF |Privileged mode only. Internal I/O register access. No cache. |P4 |} ==Physical address format== With exception of the P4 area, the different logical address areas share the same physical address space. This address space (of 29 bits) is divided into eight different areas of 64MB size each. {|class=wikitable !Physical address !Contents !Name |- |0x00000000-0x03FFFFFF |Boot ROM (2MB) Flash ROM (256K) Hardware registers |Area 0 |- |0x04000000-0x07FFFFFF |Video RAM (8MB) |Area 1 |- |0x08000000-0x0BFFFFFF | |Area2 |- |0x0C000000-0x0FFFFFFF |System RAM (16MB) |Area 3 |- |0x10000000-0x13FFFFFF |Tile accelerator command input |Area 4 |- |0x14000000-0x17FFFFFF |Expansion (modem) port |Area 5 |- |0x18000000-0x1BFFFFFF | |Area 6 |- |0x1C000000-0x1FFFFFFF |Internal I/O registers (same as P4) |Area 7 |} Accesses to Area 7 require the CPU to be running in privileged mode even if the access is through U0. ==References== <references/> ab357e66c01579d7549f0e253e6a77cbb4e8280f Licensed games and software 0 144 447 2020-01-12T05:41:47Z Unknown user 0 Created page with "{| class="wikitable" |+List of Dreamcast games released in the West |- ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |1..." wikitext text/x-wiki {| class="wikitable" |+List of Dreamcast games released in the West |- ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |- | |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |- |Alone in the Dark - The New Nightmare |- | |Aqua GT |- |Armada |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |- |BANG! - Gunship Elite |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |Cyber Troopers - Virtual On Oratorio Tangram |- |D2 |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |- |Deep Fighter |- |Demolition Racer - No Exit |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |- |ESPN International Track & Field |- |ESPN NBA 2night |- | |European Super League |- |Evil Dead - Hail to the King |- | |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- | |Exhibition of Speed |- |Expendable |- | |F1 Racing Championship |- |F1 World Grand Prix |- | |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |- |Fighting Force 2 |- | |Fighting Vipers 2 |- |Flag to Flag |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |- |Fur Fighters |- |Gauntlet Legends |- | |Giant Killers |- |GigaWing |- |GigaWing 2 |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |- | |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |- |Hydro Thunder |- |Illbleed |- |Incoming |- |Industrial Spy - Operation Espionage |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- | |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |- |The King of Fighters Evolution |- |The Last Blade 2 |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |- |Max Steel - Covert Missions |- |Maximum Pool |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |- | |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |- |NBA 2K |- |NBA 2K1 |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |- |The Next Tetris - On-line Edition |- |NFL 2K |- |NFL 2K1 |- |NFL 2K2 |- |NFL Blitz 2000 |- |NFL Blitz 2001 |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |- |NHL 2K |- |NHL 2K2 |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- | |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |- | |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- | |Rez |- |The Ring - Terror's Realm |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |- |Sega GT |- |Sega Marine Fishing |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |- | |Sega Worldwide Soccer 2000 |- | |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- | |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- | |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- | |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |- | |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |Who Wants to Beat Up a Millionaire |- |Wild Metal |- |World Series Baseball 2K1 |- |World Series Baseball 2K2 |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} 77c1bb66ba7961037206d87d5215ddb92f970df3 448 447 2020-01-12T05:49:22Z Unknown user 0 wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |- | |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |- |Alone in the Dark - The New Nightmare |- | |Aqua GT |- |Armada |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |- |BANG! - Gunship Elite |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |Cyber Troopers - Virtual On Oratorio Tangram |- |D2 |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |- |Deep Fighter |- |Demolition Racer - No Exit |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |- |ESPN International Track & Field |- |ESPN NBA 2night |- | |European Super League |- |Evil Dead - Hail to the King |- | |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- | |Exhibition of Speed |- |Expendable |- | |F1 Racing Championship |- |F1 World Grand Prix |- | |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |- |Fighting Force 2 |- | |Fighting Vipers 2 |- |Flag to Flag |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |- |Fur Fighters |- |Gauntlet Legends |- | |Giant Killers |- |GigaWing |- |GigaWing 2 |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |- | |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |- |Hydro Thunder |- |Illbleed |- |Incoming |- |Industrial Spy - Operation Espionage |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- | |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |- |The King of Fighters Evolution |- |The Last Blade 2 |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |- |Max Steel - Covert Missions |- |Maximum Pool |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |- | |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |- |NBA 2K |- |NBA 2K1 |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |- |The Next Tetris - On-line Edition |- |NFL 2K |- |NFL 2K1 |- |NFL 2K2 |- |NFL Blitz 2000 |- |NFL Blitz 2001 |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |- |NHL 2K |- |NHL 2K2 |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- | |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |- | |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- | |Rez |- |The Ring - Terror's Realm |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |- |Sega GT |- |Sega Marine Fishing |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |- | |Sega Worldwide Soccer 2000 |- | |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- | |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- | |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- | |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |- | |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |Who Wants to Beat Up a Millionaire |- |Wild Metal |- |World Series Baseball 2K1 |- |World Series Baseball 2K2 |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= =List of North American demos= =List of PAL demos= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= e98fdaafc87b71565c82e509cc40c74daa49dcc1 449 448 2020-01-12T06:05:18Z Unknown user 0 /* List of PAL demos */ wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |- | |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |- |Alone in the Dark - The New Nightmare |- | |Aqua GT |- |Armada |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |- |BANG! - Gunship Elite |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |Cyber Troopers - Virtual On Oratorio Tangram |- |D2 |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |- |Deep Fighter |- |Demolition Racer - No Exit |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |- |ESPN International Track & Field |- |ESPN NBA 2night |- | |European Super League |- |Evil Dead - Hail to the King |- | |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- | |Exhibition of Speed |- |Expendable |- | |F1 Racing Championship |- |F1 World Grand Prix |- | |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |- |Fighting Force 2 |- | |Fighting Vipers 2 |- |Flag to Flag |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |- |Fur Fighters |- |Gauntlet Legends |- | |Giant Killers |- |GigaWing |- |GigaWing 2 |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |- | |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |- |Hydro Thunder |- |Illbleed |- |Incoming |- |Industrial Spy - Operation Espionage |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- | |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |- |The King of Fighters Evolution |- |The Last Blade 2 |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |- |Max Steel - Covert Missions |- |Maximum Pool |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |- | |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |- |NBA 2K |- |NBA 2K1 |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |- |The Next Tetris - On-line Edition |- |NFL 2K |- |NFL 2K1 |- |NFL 2K2 |- |NFL Blitz 2000 |- |NFL Blitz 2001 |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |- |NHL 2K |- |NHL 2K2 |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- | |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |- | |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- | |Rez |- |The Ring - Terror's Realm |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |- |Sega GT |- |Sega Marine Fishing |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |- | |Sega Worldwide Soccer 2000 |- | |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- | |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- | |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- | |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |- | |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |Who Wants to Beat Up a Millionaire |- |Wild Metal |- |World Series Baseball 2K1 |- |World Series Baseball 2K2 |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= =List of North American demos= =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= 18ab96cfca3b2fb2cd000171eb792974707747ef 450 449 2020-01-12T06:09:43Z Unknown user 0 wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |- | |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |- |Alone in the Dark - The New Nightmare |- | |Aqua GT |- |Armada |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |- |BANG! - Gunship Elite |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |Cyber Troopers - Virtual On Oratorio Tangram |- |D2 |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |- |Deep Fighter |- |Demolition Racer - No Exit |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |- |ESPN International Track & Field |- |ESPN NBA 2night |- | |European Super League |- |Evil Dead - Hail to the King |- | |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- | |Exhibition of Speed |- |Expendable |- | |F1 Racing Championship |- |F1 World Grand Prix |- | |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |- |Fighting Force 2 |- | |Fighting Vipers 2 |- |Flag to Flag |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |- |Fur Fighters |- |Gauntlet Legends |- | |Giant Killers |- |GigaWing |- |GigaWing 2 |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |- | |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |- |Hydro Thunder |- |Illbleed |- |Incoming |- |Industrial Spy - Operation Espionage |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- | |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |- |The King of Fighters Evolution |- |The Last Blade 2 |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |- |Max Steel - Covert Missions |- |Maximum Pool |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |- | |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |- |NBA 2K |- |NBA 2K1 |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |- |The Next Tetris - On-line Edition |- |NFL 2K |- |NFL 2K1 |- |NFL 2K2 |- |NFL Blitz 2000 |- |NFL Blitz 2001 |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |- |NHL 2K |- |NHL 2K2 |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- | |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |- | |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- | |Rez |- |The Ring - Terror's Realm |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |- |Sega GT |- |Sega Marine Fishing |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |- | |Sega Worldwide Soccer 2000 |- | |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- | |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- | |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- | |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |- | |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |Who Wants to Beat Up a Millionaire |- |Wild Metal |- |World Series Baseball 2K1 |- |World Series Baseball 2K2 |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= =List of North American demos= =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= 183fa4d9c563991e6ecb80530c2131bbe5675616 451 450 2020-01-12T06:33:20Z Unknown user 0 wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |Cyber Troopers - Virtual On Oratorio Tangram |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= =List of North American demos= =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= 76e5152b3ae191c14fc8dfbbf328a2fa779f2d75 Boot process 0 20 454 180 2020-01-12T06:38:52Z Unknown user 0 wikitext text/x-wiki In general, the boot process is something like this:<br> # Dreamcast runs BootROM code and either lands at the BIOS page or tries reading a disc # [[IP.BIN]] is loaded to 0x8c008000 # 1ST_READ.BIN (or whatever file is named directly in IP.BIN) is loaded to 0x8c010000 # SH4 jumps to IP.BIN's entry point and starts executing code # IP.BIN jumps to 1ST_READ.BIN and excutes the loaded program <br> As a form of copy protection, the 1ST_READ.BIN file is generally scrambled according to an obfuscated formula, and the Dreamcast scramble loads this binary from disc it when loading 1ST_READ.BIN into memory. Loading an unscrambled binary ends up having the effect of scrambling the binary and destroying the program.<br> <br> Using a file loader such as [[dcload-ip]] or [[dcload-serial]] bypasses this entirely and allows enterprising developers to load programs directly onto the the console.<br> <br> Other details: * 0x8c000000 is the base of the system's 16MB of RAM, accessed in privileged mode due to the SH4's 29-bit addressing method * Dreamcast system calls and bios font are stored in the region 0x8c000000 - 0x8c004000 * The region 0x8c004000 - 0x8c008000 is used by multi-disc games to store persistent information across disc changes. This region is also used by persistent programs such as DCLOAD-IP/DCLOAD-SERIAL so that terminating programs can return to those loaders. * 0x8c008000 - 0x8c010000, which is used by IP.BIN, doesn't really matter beyond initial loading unless a program absolutely needs to refer to IP.BIN. The DCLOAD-IP/DCLOAD-SERIAL loaders overwrite most of IP.BIN after they've been loaded, for example, as they don't need any of it. 7b007d3894b366437b28bcd449e251b7ac57364d GD-ROM drive 0 145 455 2020-01-12T06:40:07Z Unknown user 0 Created page with "The '''GD-ROM drive''' is the optical storage drive used by the Dreamcast console. The GD-ROM security can be disabled by use of a [[System Disc 2]]. {{DCWiki:Stub}}" wikitext text/x-wiki The '''GD-ROM drive''' is the optical storage drive used by the Dreamcast console. The GD-ROM security can be disabled by use of a [[System Disc 2]]. {{DCWiki:Stub}} cf3c60a86a8682e97b47bafa4c958f9d9074396f Unlicensed software 0 146 456 2020-01-12T06:51:37Z Unknown user 0 Created page with "{| class="wikitable" !Name !Regions |- |Action Replay CDX |- |Cheats 'n' Codes Vol. 1 |- |Code Breaker |- |DC-X |- |DC-IE Import Enabler |- |Dream VCD Player |- |GameShark CDX..." wikitext text/x-wiki {| class="wikitable" !Name !Regions |- |Action Replay CDX |- |Cheats 'n' Codes Vol. 1 |- |Code Breaker |- |DC-X |- |DC-IE Import Enabler |- |Dream VCD Player |- |GameShark CDX |- |GameShark Lite |- |MP3DC (Blaze) |- |MP3DC (Pelican) |- |Planet DC Cheats |- |Super Game Converter |- |Xploder DC |} 8aec0fdb2212e26120e506fab8c80603ccaca83c VMU hardware overview 0 147 458 2020-01-12T07:00:05Z Unknown user 0 Created page with "* '''CPU''': Sanyo LC86K87 (8-bit CPU, energy saving)[7] * '''Memory''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function[7] * '''Display'..." wikitext text/x-wiki * '''CPU''': Sanyo LC86K87 (8-bit CPU, energy saving)[7] * '''Memory''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function[7] * '''Display''': 48 dot Width x 32 dot Height resolution,[7] Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip,[7] 1-channel PWM sound source 45f5408d92126f2a5aa94e723e010806a9130cbb 459 458 2020-01-12T07:00:55Z Unknown user 0 wikitext text/x-wiki * '''CPU''': Sanyo LC86K87 (8-bit CPU, energy saving) * '''Memory''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source 2ab8f5374db3a7b1887bd5b101d04eac3540e135 463 459 2020-01-12T16:23:35Z Unknown user 0 Adding more hardware details wikitext text/x-wiki * '''CPU''': Sanyo LC86K87 * ''''6Mhz clock when attached to Dreamcast controller * ''''32Khz clock when used standalone * '''Memory''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': * ''''16-bit clock-timer * ''''16-bit (or 2x 8-bit) counters 866ad5a6f1e305e5291cefeee6eb8210104fe68d 464 463 2020-01-12T16:24:50Z Unknown user 0 wikitext text/x-wiki * '''CPU''': Sanyo LC86K87 @ 6Mhz (attached to controller) or 32Khz (standalone) * '''Memory''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': 16-bit clock-timer, 16-bit (or 2x 8-bit) counters 802b423878940f319f5b3e552fc95987e2c047cb 465 464 2020-01-12T16:26:59Z Unknown user 0 wikitext text/x-wiki * '''CPU''': Sanyo LC86K87 @ 6Mhz (attached to controller) or 32Khz (standalone) * '''Memory''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': 16-bit clock-timer, 16-bit (or 2x 8-bit) counters * '''Serial Interface''': Dreamcast Maple interface (connected to controller) or Synchronous 8-bit serial interface with 2 transfer channels b033164cd952964aedc019583eb56c2d7a45c50a 466 465 2020-01-12T16:29:52Z Unknown user 0 wikitext text/x-wiki * '''CPU''': Sanyo LC86K87 @ 6Mhz (attached to controller) or 32Khz (standalone) * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes WRAM * '''Flash''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': 16-bit clock-timer, 16-bit (or 2x 8-bit) counters * '''Serial Interface''': Dedicated Maple interface (connected to controller) or Synchronous 8-bit serial interface with 2 transfer channels (standalone) bcd34936bb0cb7e9678cb74263f4708effbaaa21 VMU games 0 148 460 2020-01-12T07:55:32Z Unknown user 0 Created page with "https://bswirl.kitsunet.org/vmu/game/" wikitext text/x-wiki https://bswirl.kitsunet.org/vmu/game/ 104ae9f8c82f52fc866a8faec1b1418e57c11f43 461 460 2020-01-12T07:59:17Z Unknown user 0 wikitext text/x-wiki https://bswirl.kitsunet.org/vmu/game/ {{DCWiki:Stub}} f209d6ec3bc8a342bbdf8e26723be72851421eb7 VMU hardware overview 0 147 467 466 2020-01-12T16:31:28Z Unknown user 0 wikitext text/x-wiki * '''CPU''': 8-bit Sanyo LC86K87 @ 6Mhz (attached to controller) or 32Khz (standalone) * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes WRAM * '''Flash''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': 16-bit clock-timer, 16-bit (or 2x 8-bit) counters * '''Serial Interface''': Dedicated Maple interface (connected to controller) or Synchronous 8-bit serial interface with 2 transfer channels (standalone) 62313a14c6dbd15b95d4a4c612793e11444fcf90 468 467 2020-01-12T16:33:25Z Unknown user 0 wikitext text/x-wiki * '''CPU''': 8-bit Sanyo LC86K87 @ 6Mhz (attached to controller) or 32Khz (standalone) * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes WRAM * '''Flash''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': 16-bit clock-timer, 16-bit (or 2x 8-bit) counters * '''Serial Interface''': Dedicated Maple interface (VMU-to-Dreamcast) or Synchronous 8-bit serial interface with 2 transfer channels (VMU-to-VMU) 81663219c23349990ce5e5a508fc8f99a9d7df2b 470 468 2020-01-12T17:31:31Z Unknown user 0 Added a picture of the VMU wikitext text/x-wiki [[File:VMU Device.jpg|thumb|Visual Memory Unit]] * '''CPU''': 8-bit Sanyo LC86K87 @ 6Mhz (attached to controller) or 32Khz (standalone) * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes WRAM * '''Flash''': 128 KB (200 blocks) * '''Power source''': Two CR2032 batteries with auto-off function * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Timer''': 16-bit clock-timer, 16-bit (or 2x 8-bit) counters * '''Serial Interface''': Dedicated Maple interface (VMU-to-Dreamcast) or Synchronous 8-bit serial interface with 2 transfer channels (VMU-to-VMU) 5123f66dc62fddabd6c23df505d5a682ce1eb58d File:VMU Device.jpg 6 149 469 2020-01-12T17:31:00Z Unknown user 0 wikitext text/x-wiki Picture of the Dreamcast's Visual Memory Unit 1c6089a31b2fa756c3294ee90e45fbdee2ee639e VMU development 0 99 471 368 2020-01-12T19:36:27Z Unknown user 0 Added Comstedt's site wikitext text/x-wiki Here are some reference resources to get started * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 49d1c37d92295a27be44d675bb8b92760c17d973 Development 0 2 472 353 2020-01-12T19:38:29Z Unknown user 0 Added Comstedt's site wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [[https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference]] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] fd251dac5ccbf314cf40421b5b84db637324677d 473 472 2020-01-12T19:38:53Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show Icon * Beep * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 91038ca22384cc63f4fc8e6f939c0560eacec38a 477 473 2020-01-15T05:23:57Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * Save file * Load file * Show icon * Play tone * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 4b6b958fac055a1a0d8d2f080a856643e16d1056 478 477 2020-01-15T05:24:18Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save file]] * Load file * Show icon * Play tone * Save VMU game === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] d9d48f73a061e81632cbb6f539f426bc4aebe61b 479 478 2020-01-15T05:24:59Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save file]] * [[Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 7bdea254c659f00804bf1f02f7e75b0d827700ab 480 479 2020-01-15T05:27:10Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save file]] * [[Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 291a9b3097a2e964d78d3c9e26cff71c24fdccdf 485 480 2020-01-16T05:05:28Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] * Linux ** [[Building KOS on Linux mint (or Ubuntu)]] * Windows ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * macOS ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 218b13d63c141a9ed3ea7680b7a1ff5b594c686b Hardware Tests 0 150 474 2020-01-12T20:59:42Z Unknown user 0 Create the hardware tests page and add a link to arm7wrestler wikitext text/x-wiki {{MARKDOWN}} Hardware tests serve as living documentation of the Dreamcast hardware. They can be used to verify that behavior matches expectations, or take timing measurements. They can be burnt to a CD and run on retail Dreamcast systems to prove that the test is correct, or they can be used to test clone systems and emulators for correctness. ## Arm7Wrestler DC * Download : [https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz](https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz) * Source Code : [https://github.com/snickerbockers/dc-arm7wrestler](https://github.com/snickerbockers/dc-arm7wrestler) * Purpose : Tests for CPU bugs in the AICA's ARM7DI. 947e77e078b225977963ff190ba31e9824870402 DCWiki:Software 4 81 475 453 2020-01-12T21:00:33Z Unknown user 0 add a link to the hardware tests page wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 35d22641502a5960105fb2caae05a16a595e95fd MR image 0 73 476 392 2020-01-15T05:18:59Z Unknown user 0 Added algorithms and finishing touches to about section wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <pre> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, input_size): run = 0 length = 0 position = 0 while(position < input_size): run = 1 while((run < 0x17f) and (position+run < input_size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </pre> ==Decoding Algorithm== <pre> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </pre> 27fc1440bd3cea71ee8105eeb6607e11449437a7 File:Kos setup script.zip 6 151 481 2020-01-15T05:30:37Z Unknown user 0 wikitext text/x-wiki Kos setup script taken from DCEmulation 360af735f8b3f168192bf865981e28995eb8368b Talk:VMU 1 153 483 2020-01-15T17:08:19Z Unknown user 0 Created page with "[http://dev.dcemulation.org/tutorials/all-about-vmu.htm http://dev.dcemulation.org/tutorials/all-about-vmu.htm] --~~~~" wikitext text/x-wiki [http://dev.dcemulation.org/tutorials/all-about-vmu.htm http://dev.dcemulation.org/tutorials/all-about-vmu.htm] --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 09:08, 15 January 2020 (PST) 1e22c3cd46fccde5d34d5177d18ef844b7eea3cd Overclocking 0 154 484 2020-01-15T21:59:01Z Unknown user 0 Created page with "http://dansprojects.com/dc_overclock.html" wikitext text/x-wiki http://dansprojects.com/dc_overclock.html 64a628cf17cd3db6b09556b75fbc877cd4408589 DCDigital 0 14 486 283 2020-01-16T12:16:20Z Unknown user 0 wikitext text/x-wiki DCHDMI is a modification kit created by chriz2600 and citrus3000psi which adds native HDMI output to the Sega Dreamcast. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Installation === [https://www.youtube.com/watch?v=0c3iSYbLoH8 DCHDMI Install from start to finish] {{DCWiki:Stub}} d9bcb8f9a529c8b2946c2ba6179ae14d2b7a98ac 487 486 2020-01-16T21:07:08Z Unknown user 0 wikitext text/x-wiki DCHDMI is a modification kit created by chriz2600 and citrus3000psi which adds native HDMI output to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. All current hardware modifications, such as overclocking, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCHDMI. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Links === * [http://www.dansprojects.com/dchdmi_install.html Installation instructions] * DCHDMI Installation video: [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * [https://dc.i74.de/ Latest firmware] {{DCWiki:Stub}} c0f81a61fbc420bd4da8d80dc2e923c74aec0026 Texconv 0 155 488 2020-01-16T23:02:36Z Unknown user 0 Created page with "== Description == Texconv is a old but trusty tool to convert .png files into .dtex (some say .dtx) format. == Installation == Tested on Linux Mint (2020-01-16) sudo apt i..." wikitext text/x-wiki == Description == Texconv is a old but trusty tool to convert .png files into .dtex (some say .dtx) format. == Installation == Tested on Linux Mint (2020-01-16) sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make dea62350e12eb6b8009219930bc9d1070268ee32 489 488 2020-01-16T23:03:01Z Unknown user 0 wikitext text/x-wiki == Description == Texconv is a old but trusty tool to convert .png files into .dtex (some say .dtx) format. '''Source : ''' https://github.com/tvspelsfreak/texconv == Installation == Tested on Linux Mint (2020-01-16) sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make 159d188312f4d82dd5e64cddf30609e59de8fe4a File:Dreamcast F1 fuse resistor.png 6 156 490 2020-01-17T21:58:48Z Unknown user 0 wikitext text/x-wiki This is a closeup shot of a blown Dreamcast F1 fuse resistor 277bd5b9a83f09eb4c6cb14c321ab3ab08553d61 F1 fuse repair 0 95 491 285 2020-01-17T22:12:46Z Unknown user 0 I took measurements of the resistors on the controller port and went and tried to match them with actual part numbers. wikitext text/x-wiki [[File:Dreamcast F1 fuse resistor.png|thumb|right|150px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications. (it is actually a little bit better, and as of January 2020 it costs less then $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1 K increase in temperature, the resistance may change by roughly 20 parts per million. <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. <br> <br> {{DCWiki:Stub}} 24e83b68fc6d0a4d3d0465dfeab9212aab22e94f 492 491 2020-01-17T22:13:59Z Unknown user 0 spurious period wikitext text/x-wiki [[File:Dreamcast F1 fuse resistor.png|thumb|right|150px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less then $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1 K increase in temperature, the resistance may change by roughly 20 parts per million. <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. <br> <br> {{DCWiki:Stub}} 547b12117f235ce8b2696228aa951ca2d019ffe6 494 492 2020-01-17T22:31:28Z Unknown user 0 Fix a typo, add controller board rear view wikitext text/x-wiki [[File:Dreamcast F1 fuse resistor.png|thumb|right|150px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> [[File:Dreamcast controller board rear view.png|640px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1 K increase in temperature, the resistance may change by roughly 20 parts per million. <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. 5a285e0482603eeabdf6696c4ce1acdfaf5b4668 495 494 2020-01-17T22:47:04Z Unknown user 0 Make this page not look terrible on mobile wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|640px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] [[File:Dreamcast F1 fuse resistor.png|thumb|right|100px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1 K increase in temperature, the resistance may change by roughly 20 parts per million. <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. d6dcb20db03c81abdd095853f6ac3324a3cc0724 496 495 2020-01-17T22:55:04Z Unknown user 0 Add note about R1, offset F1 image a little bit more. Looks better on mobile now, too wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|640px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|100px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1 K increase in temperature, the resistance may change by roughly 20 parts per million. A good quality resistor <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. ccea4cbd53061f3f22cd77fe0bd2ea7a343dea80 497 496 2020-01-17T23:03:21Z Unknown user 0 Add reference for datasheet of 0.39 ohm part, explain temperature coefficient wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|640px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|100px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K = 1°C increase in temperature, the resistance may change by no more than 20 parts per million. This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 25ppm/°C above 70°C (and 0ppm/°C below).<ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. c69aacabc09848a26191f0d2001eddb57dfb509f 498 497 2020-01-17T23:11:13Z Unknown user 0 Fix ppm/K number and ppm/K description. This info is actually pretty important for a fuse. wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|640px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|100px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K = 1°C increase in temperature, the resistance may change by no more than 20 parts per million. This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C. <ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. 556d911ba75d71d310f9cb50eaa5637715c3ef80 499 498 2020-01-17T23:13:55Z Unknown user 0 This is mildly esoteric information, so put a source for it wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|640px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|100px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K = 1°C increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C. <ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. 92101103d023855af481de197c0ae983a295cedb 500 499 2020-01-18T10:36:56Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K = 1°C increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C. <ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. 4de29081826aa780c6b034931ab5c29852cf232b File:Dreamcast controller board rear view.png 6 157 493 2020-01-17T22:29:32Z Unknown user 0 wikitext text/x-wiki Rear view of a Dreamcast VA1 controller board 7c2c62e81d5d3091a3bcd430cbd563901dcf1929 File:GDR discs at Sega.jpg 6 158 501 2020-01-18T10:50:23Z Unknown user 0 Some GD-ROMs shown on Sega social media wikitext text/x-wiki == Summary == Some GD-ROMs shown on Sega social media 5b2a7da26cb692a9c848c4ec59894eb61228b086 502 501 2020-01-18T20:17:25Z Unknown user 0 Darc moved page [[File:2742924572 2219efeab7 o.jpg]] to [[File:GDR discs at Sega.jpg]] without leaving a redirect wikitext text/x-wiki == Summary == Some GD-ROMs shown on Sega social media 5b2a7da26cb692a9c848c4ec59894eb61228b086 GD-ROM 0 7 503 162 2020-01-18T20:28:24Z Unknown user 0 wikitext text/x-wiki The GD-ROM format is Sega's proprietary disc format used for the Sega Dreamcast home console, as well as for the arcade systems [[NAOMI]], [[NAOMI 2]], Triforce, and Chihiro. Holds a [[0GDTEX.PVR]] image that can be shown on the Bios CD player screen. ==GD-R discs== [[File:GDR discs at Sega.jpg|400px|thumb|right|GD-R discs stored at Sega of America]] GD-R discs are the recordable version of Sega's proprietary disc format. GD-Rs lack the security ring between the standard density and high density sections, and thus only boot on a retail Dreamcast system using a [[System Disc 2]]. The [[Katana Dev.box]] will also play these discs. 31f3420ea764ef67c7e394692895564374125f4a VRAM 0 159 504 2020-01-19T04:14:14Z Unknown user 0 add a page about VRAM wikitext text/x-wiki = Introduction = Video RAM (sometimes called texture memory) is RAM which can be referenced by the [[PowerVR2]] GPU. It is used to store textures for 3D rendering, the framebuffer, and display lists. Dreamcast has 8MB of VRAM, while Katana and NAOMI both have 16MB of VRAM. Dreamcast's VRAM consists of two separate modules which are both 4MB long. On Dreamcast VRAM is accessible to the SH4's [[memory map]] in the address range 0x04000000-0x07FFFFFF. =Memory Map= {|class=wikitable !Physical Address !Contents |- |0x04000000-0x047FFFFF |64-bit access area |- |0x04800000-0x04FFFFFF |Unused |- |0x05000000-0x057FFFFF |32-bit access area |- |0x05800000-0x05FFFFFF |Unused |- |0x06000000-0x067FFFFF |64-bit access area (mirror) |- |0x06800000-0x06FFFFFF |Unused |- |0x07000000-0x077FFFFF |32-bit access area (mirror) |- |0x07800000-0x07FFFFFF |Unused |} =64-bit and 32-bit access areas= VRAM can be accessed through one of two areas: the 64-bit area or the 32-bit area. Both areas are backed by the same physical memory. Physical VRAM consists of two separate 4MB modules, and the difference between the 32-bit and 64-bit areas is in how those two modules are mapped to addresses. The 32-bit area is used to store the framebuffer, and the 64-bit area is used to store textures. Although these two areas are referred to as "32-bit" and "64-bit" areas, there is no restriction on what sizes may be used for read and write operations. The names reflect the fact that the 64-bit area's interleaving allows it to be accessed faster than the 32-bit area since each consecutive set of four bytes comes from alternating RAM modules <ref name=comstedtpvr>''[http://mc.pp.se/dc/pvr.html]'',Dreamcast Programming - PowerVR</ref>. The 32-bit area allows for sequential access across all 8MB of VRAM, with the entirety of the second 4MB module placed after the first 4MB module. The 64-bit memory interleaves the first 4MB module with the second 4MB module, alternating between the two modules every four bytes <ref name=comstedtpvr />. So, every second set of four bytes in 64-bit area is offset by 4MB in the 32-bit area as illustrated in the table below. ===Example Address Mapping between 32-bit and 64-bit areas=== {|class=wikitable !64-bit Area Address !32-bit Area Address |- |0x04000000 |0x05000000 |- |0x04000004 |0x05400000 |- |0x04000008 |0x05000004 |- |0x0400000c |0x05400004 |- |0x04000010 |0x05000008 |- |0x04000014 |0x05400008 |- |0x04000018 |0x0500000C |- |0x0400001C |0x0540000C |} =Mirrors of 64-bit and 32-bit access areas= These are alternate ranges of addresses that can be used to access VRAM. There is no difference between using these and the above sets of addresses. They both access the exact same memory in the exact same way. =Unused areas= These 8MB ranges represent where the extra memory in NAOMI and Katana would go. In Dreamcast there is nothing here. Reading from these ranges will always return all bits set. They can be written to, but the values written will be discarded. =References= <references/> 427571356250b21c7ac07e8d76637cf243ef28c7 508 504 2020-01-19T04:34:15Z Unknown user 0 Snickerbockers moved page [[Vram]] to [[VRAM]]: make it all-caps wikitext text/x-wiki = Introduction = Video RAM (sometimes called texture memory) is RAM which can be referenced by the [[PowerVR2]] GPU. It is used to store textures for 3D rendering, the framebuffer, and display lists. Dreamcast has 8MB of VRAM, while Katana and NAOMI both have 16MB of VRAM. Dreamcast's VRAM consists of two separate modules which are both 4MB long. On Dreamcast VRAM is accessible to the SH4's [[memory map]] in the address range 0x04000000-0x07FFFFFF. =Memory Map= {|class=wikitable !Physical Address !Contents |- |0x04000000-0x047FFFFF |64-bit access area |- |0x04800000-0x04FFFFFF |Unused |- |0x05000000-0x057FFFFF |32-bit access area |- |0x05800000-0x05FFFFFF |Unused |- |0x06000000-0x067FFFFF |64-bit access area (mirror) |- |0x06800000-0x06FFFFFF |Unused |- |0x07000000-0x077FFFFF |32-bit access area (mirror) |- |0x07800000-0x07FFFFFF |Unused |} =64-bit and 32-bit access areas= VRAM can be accessed through one of two areas: the 64-bit area or the 32-bit area. Both areas are backed by the same physical memory. Physical VRAM consists of two separate 4MB modules, and the difference between the 32-bit and 64-bit areas is in how those two modules are mapped to addresses. The 32-bit area is used to store the framebuffer, and the 64-bit area is used to store textures. Although these two areas are referred to as "32-bit" and "64-bit" areas, there is no restriction on what sizes may be used for read and write operations. The names reflect the fact that the 64-bit area's interleaving allows it to be accessed faster than the 32-bit area since each consecutive set of four bytes comes from alternating RAM modules <ref name=comstedtpvr>''[http://mc.pp.se/dc/pvr.html]'',Dreamcast Programming - PowerVR</ref>. The 32-bit area allows for sequential access across all 8MB of VRAM, with the entirety of the second 4MB module placed after the first 4MB module. The 64-bit memory interleaves the first 4MB module with the second 4MB module, alternating between the two modules every four bytes <ref name=comstedtpvr />. So, every second set of four bytes in 64-bit area is offset by 4MB in the 32-bit area as illustrated in the table below. ===Example Address Mapping between 32-bit and 64-bit areas=== {|class=wikitable !64-bit Area Address !32-bit Area Address |- |0x04000000 |0x05000000 |- |0x04000004 |0x05400000 |- |0x04000008 |0x05000004 |- |0x0400000c |0x05400004 |- |0x04000010 |0x05000008 |- |0x04000014 |0x05400008 |- |0x04000018 |0x0500000C |- |0x0400001C |0x0540000C |} =Mirrors of 64-bit and 32-bit access areas= These are alternate ranges of addresses that can be used to access VRAM. There is no difference between using these and the above sets of addresses. They both access the exact same memory in the exact same way. =Unused areas= These 8MB ranges represent where the extra memory in NAOMI and Katana would go. In Dreamcast there is nothing here. Reading from these ranges will always return all bits set. They can be written to, but the values written will be discarded. =References= <references/> 427571356250b21c7ac07e8d76637cf243ef28c7 Memory map 0 105 505 446 2020-01-19T04:19:13Z Unknown user 0 add a link to the new VRAM page wikitext text/x-wiki = Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming: Memory Map, Marcus Comstedt</ref> When the built-in MMU is active, the mapping between logical and physical address is basically left up to the programmer (see the SH4 Hardware Manual for details), however the normal mode of operation in the Dreamcast is to have the MMU disabled, in which the mapping is fixed as described below. = Logical address format= When the MMU is disabled, the 32-bit logical addresses have the following format: {| class=wikitable ! 31 ! 30 ! 29 ! 28 ... 0 |- | P | ALT | NC | Physical address |} === Modifier Bits === In addition to the physical address, the following modifier bits are used: {|class=wikitable ! P | Privileged Access | Addresses with the P bit set can only be accessed when the CPU is running in privileged mode, that is when the MD bit in the status register is set. An exception to this is the Store Queue though. P inhibits the MMU, and enables the ALT and NC bits. If P is not set, ALT and NC are ignored. |- ! ALT | Alternate Address Space | Setting this bit gives an alternate mapping of the physical address bits. If NC is also set, the builtin CPU I/O registers are selected. If NC is not set, MMU translation is selected (if MMU is enabled) even though P is set. |- ! NC | Not Cacheable | Setting this bit circumvents the data cache, which is useful for accessing external hardware registers. |} === Modifier Bit Combinations === The following table shows the possible combinations of the modifier bits: {|class=wikitable !P !ALT !NC !Address range !Description !Area name |- |0 |X |X |0x00000000-0x7FFFFFFF (Physical address space repeats 4 times) |Address translation through MMU (if enabled). Can be accessed in both User and Privileged mode. |U0/P0 |- |1 |0 |0 |0x80000000-0x9FFFFFFF |Privileged mode only. |P1 |- |1 |0 |1 |0xA0000000-0xBFFFFFFF |Privileged mode only, no cache. |P2 |- |1 |1 |0 |0xC0000000-0xDFFFFFFF |Privileged mode only. Address translation through MMU (if enabled). |P3 |- |1 |1 |1 |0xE0000000-0xFFFFFFFF |Privileged mode only. Internal I/O register access. No cache. |P4 |} ==Physical address format== With exception of the P4 area, the different logical address areas share the same physical address space. This address space (of 29 bits) is divided into eight different areas of 64MB size each. {|class=wikitable !Physical address !Contents !Name |- |0x00000000-0x03FFFFFF |Boot ROM (2MB) Flash ROM (256K) Hardware registers |Area 0 |- |0x04000000-0x07FFFFFF |[[#VRAM|Video RAM (8MB)]] |Area 1 |- |0x08000000-0x0BFFFFFF | |Area2 |- |0x0C000000-0x0FFFFFFF |System RAM (16MB) |Area 3 |- |0x10000000-0x13FFFFFF |Tile accelerator command input |Area 4 |- |0x14000000-0x17FFFFFF |Expansion (modem) port |Area 5 |- |0x18000000-0x1BFFFFFF | |Area 6 |- |0x1C000000-0x1FFFFFFF |Internal I/O registers (same as P4) |Area 7 |} Accesses to Area 7 require the CPU to be running in privileged mode even if the access is through U0. ==References== <references/> 34f973ac56e0a1b3da9be2e54fdfd38ba0359b8b 507 505 2020-01-19T04:26:59Z Unknown user 0 I accidentally did the link wrong in my last edit wikitext text/x-wiki = Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming: Memory Map, Marcus Comstedt</ref> When the built-in MMU is active, the mapping between logical and physical address is basically left up to the programmer (see the SH4 Hardware Manual for details), however the normal mode of operation in the Dreamcast is to have the MMU disabled, in which the mapping is fixed as described below. = Logical address format= When the MMU is disabled, the 32-bit logical addresses have the following format: {| class=wikitable ! 31 ! 30 ! 29 ! 28 ... 0 |- | P | ALT | NC | Physical address |} === Modifier Bits === In addition to the physical address, the following modifier bits are used: {|class=wikitable ! P | Privileged Access | Addresses with the P bit set can only be accessed when the CPU is running in privileged mode, that is when the MD bit in the status register is set. An exception to this is the Store Queue though. P inhibits the MMU, and enables the ALT and NC bits. If P is not set, ALT and NC are ignored. |- ! ALT | Alternate Address Space | Setting this bit gives an alternate mapping of the physical address bits. If NC is also set, the builtin CPU I/O registers are selected. If NC is not set, MMU translation is selected (if MMU is enabled) even though P is set. |- ! NC | Not Cacheable | Setting this bit circumvents the data cache, which is useful for accessing external hardware registers. |} === Modifier Bit Combinations === The following table shows the possible combinations of the modifier bits: {|class=wikitable !P !ALT !NC !Address range !Description !Area name |- |0 |X |X |0x00000000-0x7FFFFFFF (Physical address space repeats 4 times) |Address translation through MMU (if enabled). Can be accessed in both User and Privileged mode. |U0/P0 |- |1 |0 |0 |0x80000000-0x9FFFFFFF |Privileged mode only. |P1 |- |1 |0 |1 |0xA0000000-0xBFFFFFFF |Privileged mode only, no cache. |P2 |- |1 |1 |0 |0xC0000000-0xDFFFFFFF |Privileged mode only. Address translation through MMU (if enabled). |P3 |- |1 |1 |1 |0xE0000000-0xFFFFFFFF |Privileged mode only. Internal I/O register access. No cache. |P4 |} ==Physical address format== With exception of the P4 area, the different logical address areas share the same physical address space. This address space (of 29 bits) is divided into eight different areas of 64MB size each. {|class=wikitable !Physical address !Contents !Name |- |0x00000000-0x03FFFFFF |Boot ROM (2MB) Flash ROM (256K) Hardware registers |Area 0 |- |0x04000000-0x07FFFFFF |[[Video RAM]] (8MB) |Area 1 |- |0x08000000-0x0BFFFFFF | |Area2 |- |0x0C000000-0x0FFFFFFF |System RAM (16MB) |Area 3 |- |0x10000000-0x13FFFFFF |Tile accelerator command input |Area 4 |- |0x14000000-0x17FFFFFF |Expansion (modem) port |Area 5 |- |0x18000000-0x1BFFFFFF | |Area 6 |- |0x1C000000-0x1FFFFFFF |Internal I/O registers (same as P4) |Area 7 |} Accesses to Area 7 require the CPU to be running in privileged mode even if the access is through U0. ==References== <references/> 98ff637f00f4db22c3dc11edd3b1098c4d046f3e Video RAM 0 160 506 2020-01-19T04:25:56Z Unknown user 0 Redirected page to [[Vram]] wikitext text/x-wiki #REDIRECT [[Vram]] e585e5e9657e77b95381809592660a9e6220f421 510 506 2020-01-19T04:35:46Z Unknown user 0 Changed redirect target from [[Vram]] to [[VRAM]] wikitext text/x-wiki #REDIRECT [[VRAM]] 0f9eb09304cad33db23e4e01b45a5c60a6cc3793 Vram 0 161 509 2020-01-19T04:34:16Z Unknown user 0 Snickerbockers moved page [[Vram]] to [[VRAM]]: make it all-caps wikitext text/x-wiki #REDIRECT [[VRAM]] 0f9eb09304cad33db23e4e01b45a5c60a6cc3793 File:DCFlash.zip 6 162 511 2020-01-19T05:26:27Z Unknown user 0 Dreamcast Flash Memory Eraser wikitext text/x-wiki == Summary == Dreamcast Flash Memory Eraser 0a29d448976c37f8e6a44c4af7dc30bf5445e008 Other Dreamcast software 0 109 512 310 2020-01-19T05:26:56Z Unknown user 0 wikitext text/x-wiki * [[CBLoader]] * [[DCHakker]] * [[DemoMenu]] * [[DreamExplorer/VMUTool]] * [[DreamShell]] * [[Dream Photo Manager]] * [[Flash Internet Settings Adjuster]] * [[Flash Memory Eraser]] * [[LinuxDC]] * [[NetBSD/Dreamcast]] * [[NTSC and PAL Enforcer]] * [[Sylverant PSO Patcher]] {{DCWiki:Stub}} cdf42cc43e1b644044166a9d54f4c24ae60d9874 Flash Memory Eraser 0 163 513 2020-01-19T05:29:11Z Unknown user 0 Created page with "The '''Dreamcast Flash Memory Eraser''' is a small utility that erases the entire writable Flash ROM of the Dreamcast. This is most useful for changing the serial number and a..." wikitext text/x-wiki The '''Dreamcast Flash Memory Eraser''' is a small utility that erases the entire writable Flash ROM of the Dreamcast. This is most useful for changing the serial number and access key for [[Phantasy Star Online]]. [[:File:DCFlash.zip|Download CDI image]] 5c4130aa886827bbe1cf10b55877a1d1ed93e51b 514 513 2020-01-19T05:30:18Z Unknown user 0 wikitext text/x-wiki The '''Dreamcast Flash Memory Eraser''' is a small utility that erases the entire writable flash ROM of the Dreamcast. This is most useful for changing the serial number and access key for [[Phantasy Star Online]]. When run, it will show the Sega copyright screen and display a red border; when the red border turns green, the flash ROM is erased. [[:File:DCFlash.zip|Download CDI image]] c6634e3d444d356044a210daaed6c84b5fd1368c Hardware overview 0 38 515 120 2020-01-20T02:49:52Z Unknown user 0 wikitext text/x-wiki *'''CPU''': Hitachi SuperH SH-4 RISC CPU @ 200MHz *'''GPU''': NEC PowerVR2 with 8MB of [[VRAM|texture memory]] *'''Sound''': Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memory''': 16MB system memory *'''Storage''': [[GD-ROM drive]] *'''Network''': 33.6K or 56K [[Modem|modem]] 91aa93e1cd06dc1e7f03904548c7e2d501305db0 MediaWiki:Sidebar 8 10 516 423 2020-01-20T04:47:33Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|Dreamcast Wiki Home ** forums-url|DCEmu Message Board ** simulant-discord-url|Simulant Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES b71373b91ebe32071d7849fe3b91f9d53ad7bab8 517 516 2020-01-20T04:47:43Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|Dreamcast Wiki Home ** forums-url|DCEmu Forums ** simulant-discord-url|Simulant Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES c2daef2730c055d875d974e06d37a2afda1f8a46 DCWiki:Software 4 81 518 475 2020-01-20T05:02:34Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * 3rd-party [[Unlicensed software|unlicensed software]] * Commercially sold, independently developed [[Indie games|indie games]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 9a02edb27a121e85a354ddfbf753c8c87897c1a0 558 518 2020-01-23T06:50:59Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 4d53014488aef119b95173ac5e180c83fce862e3 MIL-CD 0 64 519 304 2020-01-20T22:33:13Z Unknown user 0 expanding with text from a WIP Dream On magazine #2 article wikitext text/x-wiki [[File:Milcd_logo.png|thumb|right|Official MIL-CD logo]] '''Music Interactive Live-CD (MIL-CD)''' is a digital optical storage format created by [[Sega]]. It allows code to be loaded on the Dreamcast via standard compact disc media, such as a CD-ROM or CD-R. ==Official releases== There were eight official MIL-CD releases, distributed in Japan only, all of which were audio music CDs containing extra audiovisual content when loaded in a Dreamcast console. ==Using MIL-CD to boot independent code on the Dreamcast== It soon became apparent that it could be used to allow the Dreamcast to boot code on a standard compact disc, without needing to use the proprietary [[GD-ROM]] (Gigabyte Disc) format that Sega used for Dreamcast games (as well as some arcade games with hardware based on the Sega Dreamcast and Microsoft Xbox). The independent game development community soon discovered the MIL-CD releases and adapted them for their own code. The first demonstration of independently developed software intended for commercial sale was the [[Action Replay CDX|GameShark CDX]]. This was the localized version of [[Datel]]'s [[Action Replay CDX]], as [[Interact]] had acquired the rights for release in North America. It was shown at the [[Consumer Electronics Show]], which ran from January 6 to January 9, 2000. The first non-commercial independent code to successfully run on the Dreamcast was achieved by the demo group Hitmen. Their A.G.E. demo, a technical demo for the Dreamcast that displayed stylized text, graphics, and music, premiered at the Mekka & Symposium 2000 convention in Fallingbostel, Germany on April 23, 2000. This demo was never released publicly, as it was developed using a custom coding library and required the Dreamcast to be connected to a host computer using a custom serial port adapter known as the Dreamcast Debug Handler. The commercial [[PlayStation]] [[emulation|emulator]], [[bleemcast!]], was then demonstrated at the [[Electronics Entertainment Expo]], or E3, which ran from May 11 to May 13, 2000. The Action Replay CDX became the first independent commercial release when it was released to retail on June 2, 2000. [[Marcus Comstedt]], who would later become known for his Dreamcast ports of the [[Super Nintendo Entertainment System]] emulator [[SNES9x]] and the adventure game interpreter [[ScummVM]], reverse engineered this disc and built his own library for the Dreamcast using the open-source GNU C compiler for the SH-4 processor. He wrote documentation detailing the process of booting code directly on the Dreamcast, and released a simple "Hello World" demo on June 20, 2000. ==MIL-CD Piracy== At the same time the indie developers were reverse-engineering the MIL-CD format, software crackers discovered the loophole that was employed by the Action Replay CDX. A pirate group known as Utopia released a CD image intended to boot illegal game rips on June 22, 2000. This bootloader was quickly followed by a rip of the game ''[[Dead or Alive 2]]'' on June 23, 2000. Due to the inability of their game rips to boot on their own, all of the early pirate releases required the use of their bootloader, which became known as the Utopia Boot CD. The bootloader itself was created by modifying the teapot demo that was included with the official Sega Katana library. Other pirate groups soon released game rips in the form of self-booting images which would run on a Dreamcast directly after being burnt to a CD-R, eliminating the limitations of the Utopia Boot CD. Sega's GD-ROM format, which was meant to be a hindrance to piracy, was soon obsolete, as the only restriction towards playing illegal copies of Dreamcast games was now the slow connection speeds of most internet modems of the time. 793af575eddf5db274551b682903115518162852 520 519 2020-01-20T22:40:38Z Unknown user 0 re-adding sentence about the MIL-CD track format, expanding it, and clarifying it a bit wikitext text/x-wiki [[File:Milcd_logo.png|thumb|right|Official MIL-CD logo]] '''Music Interactive Live-CD (MIL-CD)''' is a digital optical storage format created by [[Sega]]. It allows code to be loaded on the Dreamcast via standard compact disc media, such as a CD-ROM or CD-R. MIL-CDs consist of audio tracks before the track containing Dreamcast-bootable data. Custom MIL-CDs can also be created with a data track before the Dreamcast-bootable data track. ==Official releases== There were eight official MIL-CD releases, distributed in Japan only, all of which were audio music CDs containing extra audiovisual content when loaded in a Dreamcast console. ==Using MIL-CD to boot independent code on the Dreamcast== The MIL-CD could be used to allow the Dreamcast to boot code on a standard compact disc, without needing to use the proprietary [[GD-ROM]] (Gigabyte Disc) format that Sega used for Dreamcast games (as well as some arcade games with hardware based on the Sega Dreamcast and Microsoft Xbox). The independent game development community soon discovered the MIL-CD releases and adapted them for their own code. The first demonstration of independently developed software intended for commercial sale was the [[Action Replay CDX|GameShark CDX]]. This was the localized version of [[Datel]]'s [[Action Replay CDX]], as [[Interact]] had acquired the rights for release in North America. It was shown at the [[Consumer Electronics Show]], which ran from January 6 to January 9, 2000. The first non-commercial independent code to successfully run on the Dreamcast was achieved by the demo group Hitmen. Their A.G.E. demo, a technical demo for the Dreamcast that displayed stylized text, graphics, and music, premiered at the Mekka & Symposium 2000 convention in Fallingbostel, Germany on April 23, 2000. This demo was never released publicly, as it was developed using a custom coding library and required the Dreamcast to be connected to a host computer using a custom serial port adapter known as the Dreamcast Debug Handler. The commercial [[PlayStation]] [[emulation|emulator]], [[bleemcast!]], was then demonstrated at the [[Electronics Entertainment Expo]], or E3, which ran from May 11 to May 13, 2000. The Action Replay CDX became the first independent commercial release when it was released to retail on June 2, 2000. [[Marcus Comstedt]], who would later become known for his Dreamcast ports of the [[Super Nintendo Entertainment System]] emulator [[SNES9x]] and the adventure game interpreter [[ScummVM]], reverse engineered this disc and built his own library for the Dreamcast using the open-source GNU C compiler for the SH-4 processor. He wrote documentation detailing the process of booting code directly on the Dreamcast, and released a simple "Hello World" demo on June 20, 2000. ==MIL-CD Piracy== At the same time the indie developers were reverse-engineering the MIL-CD format, software crackers discovered the loophole that was employed by the Action Replay CDX. A pirate group known as Utopia released a CD image intended to boot illegal game rips on June 22, 2000. This bootloader was quickly followed by a rip of the game ''[[Dead or Alive 2]]'' on June 23, 2000. Due to the inability of their game rips to boot on their own, all of the early pirate releases required the use of their bootloader, which became known as the Utopia Boot CD. The bootloader itself was created by modifying the teapot demo that was included with the official Sega Katana library. Other pirate groups soon released game rips in the form of self-booting images which would run on a Dreamcast directly after being burnt to a CD-R, eliminating the limitations of the Utopia Boot CD. Sega's GD-ROM format, which was meant to be a hindrance to piracy, was soon obsolete, as the only restriction towards playing illegal copies of Dreamcast games was now the slow connection speeds of most internet modems of the time. 45d918f902d47f41fdf3445dbe3a42b238cf82d3 521 520 2020-01-20T22:41:48Z Unknown user 0 slight change in wording wikitext text/x-wiki [[File:Milcd_logo.png|thumb|right|Official MIL-CD logo]] '''Music Interactive Live-CD (MIL-CD)''' is a digital optical storage format created by [[Sega]]. It allows code to be loaded on the Dreamcast via standard compact disc media, such as a CD-ROM or CD-R. MIL-CDs consist of audio tracks before the track containing Dreamcast-bootable data. Custom MIL-CDs can also be created with a data track before the Dreamcast-bootable data track. ==Official releases== There were eight official MIL-CD releases, distributed in Japan only, all of which were audio music CDs containing extra audiovisual content when loaded in a Dreamcast console. ==Using MIL-CD to boot independent code on the Dreamcast== The MIL-CD could be used to allow the Dreamcast to boot code on a standard compact disc, without needing to use the proprietary [[GD-ROM]] (Gigabyte Disc) format that Sega used for Dreamcast games (as well as some arcade games with hardware based on the Sega Dreamcast and Microsoft Xbox). The independent game development community discovered the MIL-CD releases and adapted them for their own code. The first demonstration of independently developed software intended for commercial sale was the [[Action Replay CDX|GameShark CDX]]. This was the localized version of [[Datel]]'s [[Action Replay CDX]], as [[Interact]] had acquired the rights for release in North America. It was shown at the [[Consumer Electronics Show]], which ran from January 6 to January 9, 2000. The first non-commercial independent code to successfully run on the Dreamcast was achieved by the demo group Hitmen. Their A.G.E. demo, a technical demo for the Dreamcast that displayed stylized text, graphics, and music, premiered at the Mekka & Symposium 2000 convention in Fallingbostel, Germany on April 23, 2000. This demo was never released publicly, as it was developed using a custom coding library and required the Dreamcast to be connected to a host computer using a custom serial port adapter known as the Dreamcast Debug Handler. The commercial [[PlayStation]] [[emulation|emulator]], [[bleemcast!]], was then demonstrated at the [[Electronics Entertainment Expo]], or E3, which ran from May 11 to May 13, 2000. The Action Replay CDX became the first independent commercial release when it was released to retail on June 2, 2000. [[Marcus Comstedt]], who would later become known for his Dreamcast ports of the [[Super Nintendo Entertainment System]] emulator [[SNES9x]] and the adventure game interpreter [[ScummVM]], reverse engineered this disc and built his own library for the Dreamcast using the open-source GNU C compiler for the SH-4 processor. He wrote documentation detailing the process of booting code directly on the Dreamcast, and released a simple "Hello World" demo on June 20, 2000. ==MIL-CD Piracy== At the same time the indie developers were reverse-engineering the MIL-CD format, software crackers discovered the loophole that was employed by the Action Replay CDX. A pirate group known as Utopia released a CD image intended to boot illegal game rips on June 22, 2000. This bootloader was quickly followed by a rip of the game ''[[Dead or Alive 2]]'' on June 23, 2000. Due to the inability of their game rips to boot on their own, all of the early pirate releases required the use of their bootloader, which became known as the Utopia Boot CD. The bootloader itself was created by modifying the teapot demo that was included with the official Sega Katana library. Other pirate groups soon released game rips in the form of self-booting images which would run on a Dreamcast directly after being burnt to a CD-R, eliminating the limitations of the Utopia Boot CD. Sega's GD-ROM format, which was meant to be a hindrance to piracy, was soon obsolete, as the only restriction towards playing illegal copies of Dreamcast games was now the slow connection speeds of most internet modems of the time. 6816a85410c0ae43dbaf33b19d3cf02a6584e45d LAN adapter 0 31 522 269 2020-01-22T04:01:55Z Unknown user 0 wikitext text/x-wiki The Dreamcast '''LAN Adapter (HIT-300)''' (not to be confused with the superior [[Broadband adapter]]) is a Japanese-only peripheral that connects to the [[G2 bus]] and provides the Dreamcast with 10mbps network connectivity via a Fujitsu MB86967 chip. The only official software that works with the LAN adapter is the Dream Passport for LAN web browser. No official games from any region are compatible with the LAN adapter. Homebrew software that is compatible with the Broadband adapter is also compatible with the LAN adapter, however, except that software is uncommonly tested with the adapter due to its rarity. {{DCWiki:Stub}} 374f67fc6ae6fe4d5249900a5a4c8c7c56c8ec2d Broadband adapter 0 5 523 268 2020-01-22T04:04:06Z Unknown user 0 wikitext text/x-wiki The Dreamcast '''Broadband Adapter''' ('''HIT-400''' or '''HIT-401'''), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a somewhat rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. A program loader called DCLOAD-IP<ref>https://github.com/sizious/dcload-ip</ref> is also designed for use with it to aid in Dreamcast development. {{DCWiki:Stub}} 92f1033f49e5bb65ecebe42dbe3ef6bdbd171985 527 523 2020-01-22T22:03:23Z Unknown user 0 wikitext text/x-wiki The Dreamcast '''Broadband Adapter''' ('''HIT-400''' or '''HIT-401'''), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a somewhat rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [dcload-ip] - A program made to transfer .cdi and .elf files over the BBA. Mostly intended for homebrew developement. {{DCWiki:Stub}} 0cfe5538e1bca4d98b1281b84e4528f0a7266e69 528 527 2020-01-22T22:03:37Z Unknown user 0 wikitext text/x-wiki The Dreamcast '''Broadband Adapter''' ('''HIT-400''' or '''HIT-401'''), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a somewhat rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .cdi and .elf files over the BBA. Mostly intended for homebrew developement. {{DCWiki:Stub}} 43e44f41d6000f4f0352b8effd667442f651e267 Optical drive replacements 0 16 524 48 2020-01-22T18:20:22Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Examples include: * [GDEMU] * USB-GDROM * iceGDROM ed48238f4b06587e1009aadd4600c36a327eeacb 525 524 2020-01-22T18:20:35Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Examples include: * [[GDEMU]] * USB-GDROM * iceGDROM 14656a798cd9d03f379cf380cfd694ecce20afa9 GDEMU 0 164 526 2020-01-22T18:28:16Z Unknown user 0 Created page with "The GDEMU a [[GD-ROM]] disk drive replacement. '''Offical link''' : https://gdemu.wordpress.com == Usage == ''This content has been copied from the official source'' GDEMU..." wikitext text/x-wiki The GDEMU a [[GD-ROM]] disk drive replacement. '''Offical link''' : https://gdemu.wordpress.com == Usage == ''This content has been copied from the official source'' GDEMU is compatbile with VA1 model Dreamcasts from all regions IMPORTANT: VA2 model is not compatible. Mating GDEMU with VA0 model mainboard is possible but will cause permanent damage to the device. See installation instructions. '''Supported image types:''' * GDI (for GD-ROMs) * CDI * CCD+IMG+SUB * MDS+MDF * ISO (as data carriers for homebrew) IMPORTANT: Recently some new dumping groups have been releasing GDIs dumped with PC CD-ROM drive using so-called “swap method”. Technically there is nothing wrong with it except for slightly different “offset” on audio tracks compared to what Dreamcast drive would produce, nothing you’d even notice. But they’ve changed the way track starting address is calculated and as a result all games that have digital audio, or data split beyond track #3, will not work properly. This is not a GDEMU issuse and there is no fix planned for this – avoid such dumps. '''Image layout:''' * Every image must be put in a separate folder * Folder names must consist of: ** 2 digits for 01 to 99 ** 3 digits up to 999 ** 4 digits up to 9999 *All file names must be in DOS 8.3 format *The main image file must be called “disc” with appropriate extension IMPORTANT: Long filenames are not supported, neither are names containing non-ASCII characters. You can, however, put a file named with the game title in each folder for better organization, even if it’s a long name – it will be ignored by GDEMU. An example of correct filenames for GDI image: track01.bin track03.bin disc.gdi track02.raw == Tools == 1b064170bbc0a49f21e88de713dfc127325cb4de 536 526 2020-01-22T22:25:34Z Unknown user 0 /* Tools */ wikitext text/x-wiki The GDEMU a [[GD-ROM]] disk drive replacement. '''Offical link''' : https://gdemu.wordpress.com == Usage == ''This content has been copied from the official source'' GDEMU is compatbile with VA1 model Dreamcasts from all regions IMPORTANT: VA2 model is not compatible. Mating GDEMU with VA0 model mainboard is possible but will cause permanent damage to the device. See installation instructions. '''Supported image types:''' * GDI (for GD-ROMs) * CDI * CCD+IMG+SUB * MDS+MDF * ISO (as data carriers for homebrew) IMPORTANT: Recently some new dumping groups have been releasing GDIs dumped with PC CD-ROM drive using so-called “swap method”. Technically there is nothing wrong with it except for slightly different “offset” on audio tracks compared to what Dreamcast drive would produce, nothing you’d even notice. But they’ve changed the way track starting address is calculated and as a result all games that have digital audio, or data split beyond track #3, will not work properly. This is not a GDEMU issuse and there is no fix planned for this – avoid such dumps. '''Image layout:''' * Every image must be put in a separate folder * Folder names must consist of: ** 2 digits for 01 to 99 ** 3 digits up to 999 ** 4 digits up to 9999 *All file names must be in DOS 8.3 format *The main image file must be called “disc” with appropriate extension IMPORTANT: Long filenames are not supported, neither are names containing non-ASCII characters. You can, however, put a file named with the game title in each folder for better organization, even if it’s a long name – it will be ignored by GDEMU. An example of correct filenames for GDI image: track01.bin track03.bin disc.gdi track02.raw == Tools == [[GDmenu]] - A homebrew program that let you choose between all your games/program on your SD card. d2e2beb80ebfbc4cbaa6c8fc5823a9b1bc8734f7 537 536 2020-01-22T22:26:36Z Unknown user 0 wikitext text/x-wiki The GDEMU a [[GD-ROM]] disk drive replacement. '''Offical link''' : https://gdemu.wordpress.com == Usage == ''This content has been copied from the official source'' GDEMU is compatbile with VA1 model Dreamcasts from all regions IMPORTANT: VA2 model is not compatible. Mating GDEMU with VA0 model mainboard is possible but will cause permanent damage to the device. See installation instructions. '''Supported image types:''' * GDI (for GD-ROMs) * CDI * CCD+IMG+SUB * MDS+MDF * ISO (as data carriers for homebrew) IMPORTANT: Recently some new dumping groups have been releasing GDIs dumped with PC CD-ROM drive using so-called “swap method”. Technically there is nothing wrong with it except for slightly different “offset” on audio tracks compared to what Dreamcast drive would produce, nothing you’d even notice. But they’ve changed the way track starting address is calculated and as a result all games that have digital audio, or data split beyond track #3, will not work properly. This is not a GDEMU issuse and there is no fix planned for this – avoid such dumps. '''Image layout:''' * Every image must be put in a separate folder * Folder names must consist of: ** 2 digits for 01 to 99 ** 3 digits up to 999 ** 4 digits up to 9999 *All file names must be in DOS 8.3 format *The main image file must be called “disc” with appropriate extension IMPORTANT: Long filenames are not supported, neither are names containing non-ASCII characters. You can, however, put a file named with the game title in each folder for better organization, even if it’s a long name – it will be ignored by GDEMU. An example of correct filenames for GDI image: -- track01.bin -- track03.bin -- disc.gdi -- track02.raw == Tools == [[GDmenu]] - A homebrew program that let you choose between all your games/program on your SD card. 5187804b5d9002f9b0c055c04a0af2d408fd70d2 Dcload-ip 0 23 529 69 2020-01-22T22:08:09Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. * Maintained version by SiZious : https://github.com/sizious/dcload-ip * With DHCP support by Moopthehedgehod : https://github.com/Moopthehedgehog/dcload-ip {{DISPLAYTITLE:dcload-ip}} c77ac26196849e7700efea12c4c1764d1f8e4d0c 530 529 2020-01-22T22:10:17Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip v1.04] - Maintained version by SiZious * [https://github.com/Moopthehedgehog/dcload-ip dcload-ip v1.05 + DHCP] - support by Moopthehedgehog {{DISPLAYTITLE:dcload-ip}} 5a9ecb694caa66bcde15dca733eb2811e9babc33 531 530 2020-01-22T22:10:42Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip v1.04] - maintained by SiZious * [https://github.com/Moopthehedgehog/dcload-ip dcload-ip v1.05 + DHCP] - maintained by Moopthehedgehog {{DISPLAYTITLE:dcload-ip}} d857c8abe80ebf37e1cba961dfe9e79a3b32399a DreamPi 0 18 532 281 2020-01-22T22:20:39Z Unknown user 0 wikitext text/x-wiki DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. ''Original write up by Kazade'' DreamPi is a piece of software I've written combined with a standard set of hardware which allows the SEGA Dreamcast to connect to the internet without a dial-up ISP. == Material == To build a DreamPi, you need the following hardware: * A Raspberry Pi * An SD card containing the DreamPi software image * A Linux-compatible, USB dial-up voice modem (UK | US | DE) * A telephone cable * An ethernet cable * Dreamcast browser software (e.g. Dreamkey 3.0) == Voltage Line Inducer == Chances are (regardless of region) you will also need to build a line voltage inducer. This is a simple circuit which sends an electric current down the telephone cable. For this you will need: * A 0.47uf capacitor * A 380 Ohm resistor * A 9v battery connector (two if you have a PAL modem) * A 9v battery (two if you have a PAL modem) * A soldering iron, some solder, wire strippers, electrical tape, and patience == How to setup the DreamPi == Connect the Raspberry Pi to the USB modem, connect that to the phone cable, connect the phone cable to the Dreamcast. Then, connect the Raspberry Pi into your router. Now, download the image, decompress with 7zip (or whatever) and follow the instructions here to flash the image to the SD card: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md Now, insert the SD card into the Pi, and switch it on! === Configuring DreamKey / PlanetWeb === For PlanetWeb, follow the instructions found here under "Configuring the Dreamcast". For DreamKey 3.0. You need to set the ISP number to dial to 555. So, what's the deal with PAL modems? Right, it took me ages to figure this out. U.S modems come in two forms, model "A" modems, and model "B" modems. Model A modems don't draw their power from the telephone line itself, or at least, they don't require it (some USB modems do however!). Model B modems do, and so to do a direct modem-to-modem connection with one of those you need to somehow add power to the connecting phone wire. That's what a "Line Voltage Inducer" does. The best instructions I've found for this are here. But, it gets even more complicated. Generally PAL modems are classed as Model B modems - they require a line voltage. However, I found that not many PAL users had had much luck getting connected, and when I tried, it didn't work for me either, even with a line voltage inducer! Apparently it seems that U.S. Model B modems can suffice with only 9 volts added to the telephone line, but in europe our fussy PAL modems require 18 volts! This is simple enough to do, just build the line voltage inducer as normal, but chain two 9 volt batteries together in series, rather than using just one. == Video instruction == <youtube>VgRLnj2YR3s</youtube> {{DCWiki:Stub}} bc5469eaafec8ace84bc2b828d2b2ca2f075040a 533 532 2020-01-22T22:22:19Z Unknown user 0 wikitext text/x-wiki == Description == DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. == Material == To build a DreamPi, you need the following hardware: * A Raspberry Pi * An SD card containing the DreamPi software image * A Linux-compatible, USB dial-up voice modem (UK | US | DE) * A telephone cable * An ethernet cable * Dreamcast browser software (e.g. Dreamkey 3.0) == Voltage Line Inducer == Chances are (regardless of region) you will also need to build a line voltage inducer. This is a simple circuit which sends an electric current down the telephone cable. For this you will need: * A 0.47uf capacitor * A 380 Ohm resistor * A 9v battery connector (two if you have a PAL modem) * A 9v battery (two if you have a PAL modem) * A soldering iron, some solder, wire strippers, electrical tape, and patience == How to setup the DreamPi == Connect the Raspberry Pi to the USB modem, connect that to the phone cable, connect the phone cable to the Dreamcast. Then, connect the Raspberry Pi into your router. Now, download the image, decompress with 7zip (or whatever) and follow the instructions here to flash the image to the SD card: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md Now, insert the SD card into the Pi, and switch it on! === Configuring DreamKey / PlanetWeb === For PlanetWeb, follow the instructions found here under "Configuring the Dreamcast". For DreamKey 3.0. You need to set the ISP number to dial to 555. So, what's the deal with PAL modems? Right, it took me ages to figure this out. U.S modems come in two forms, model "A" modems, and model "B" modems. Model A modems don't draw their power from the telephone line itself, or at least, they don't require it (some USB modems do however!). Model B modems do, and so to do a direct modem-to-modem connection with one of those you need to somehow add power to the connecting phone wire. That's what a "Line Voltage Inducer" does. The best instructions I've found for this are here. But, it gets even more complicated. Generally PAL modems are classed as Model B modems - they require a line voltage. However, I found that not many PAL users had had much luck getting connected, and when I tried, it didn't work for me either, even with a line voltage inducer! Apparently it seems that U.S. Model B modems can suffice with only 9 volts added to the telephone line, but in europe our fussy PAL modems require 18 volts! This is simple enough to do, just build the line voltage inducer as normal, but chain two 9 volt batteries together in series, rather than using just one. == Video instruction == <youtube>VgRLnj2YR3s</youtube> == Pre made kits == [https://www.dreamcastlive.net/shop Dreamcast Live] is selling assembled DreamPi and Voltage Line Inducers. {{DCWiki:Stub}} 1e84666ca50f13a1cfbc7e543918c03ac01d8005 534 533 2020-01-22T22:23:36Z Unknown user 0 wikitext text/x-wiki == Description == DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. == Material == To build a DreamPi, you need the following hardware: * A Raspberry Pi * An SD card containing the DreamPi software image * A Linux-compatible, USB dial-up voice modem (UK | US | DE) * A telephone cable * An ethernet cable * Dreamcast browser software (e.g. Dreamkey 3.0) == Voltage Line Inducer == Chances are (regardless of region) you will also need to build a line voltage inducer. This is a simple circuit which sends an electric current down the telephone cable. For this you will need: * A 0.47uf capacitor * A 380 Ohm resistor * A 9v battery connector (two if you have a PAL modem) * A 9v battery (two if you have a PAL modem) * A soldering iron, some solder, wire strippers, electrical tape, and patience == How to setup the DreamPi == Connect the Raspberry Pi to the USB modem, connect that to the phone cable, connect the phone cable to the Dreamcast. Then, connect the Raspberry Pi into your router. Now, download the image, decompress with 7zip (or whatever) and follow the instructions here to flash the image to the SD card: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md Now, insert the SD card into the Pi, and switch it on! == Configuring DreamKey or PlanetWeb == For PlanetWeb, follow the instructions found here under "Configuring the Dreamcast". For DreamKey 3.0. You need to set the ISP number to dial to 555. So, what's the deal with PAL modems? Right, it took me ages to figure this out. U.S modems come in two forms, model "A" modems, and model "B" modems. Model A modems don't draw their power from the telephone line itself, or at least, they don't require it (some USB modems do however!). Model B modems do, and so to do a direct modem-to-modem connection with one of those you need to somehow add power to the connecting phone wire. That's what a "Line Voltage Inducer" does. The best instructions I've found for this are here. But, it gets even more complicated. Generally PAL modems are classed as Model B modems - they require a line voltage. However, I found that not many PAL users had had much luck getting connected, and when I tried, it didn't work for me either, even with a line voltage inducer! Apparently it seems that U.S. Model B modems can suffice with only 9 volts added to the telephone line, but in europe our fussy PAL modems require 18 volts! This is simple enough to do, just build the line voltage inducer as normal, but chain two 9 volt batteries together in series, rather than using just one. == Video instruction == <youtube>VgRLnj2YR3s</youtube> == Pre made kits == [https://www.dreamcastlive.net/shop Dreamcast Live] is selling assembled DreamPi and Voltage Line Inducers. {{DCWiki:Stub}} cdbf66e32722a0cda3481f093a57adfa48c48d81 535 534 2020-01-22T22:24:14Z Unknown user 0 wikitext text/x-wiki == Description == DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. == Material == To build a DreamPi, you need the following hardware: * A Raspberry Pi * An SD card containing the DreamPi software image * A Linux-compatible, USB dial-up voice modem (UK | US | DE) * A telephone cable * An ethernet cable * Dreamcast browser software (e.g. Dreamkey 3.0) == Voltage Line Inducer == Chances are (regardless of region) you will also need to build a line voltage inducer. This is a simple circuit which sends an electric current down the telephone cable. For this you will need: * A 0.47uf capacitor * A 380 Ohm resistor * A 9v battery connector (two if you have a PAL modem) * A 9v battery (two if you have a PAL modem) * A soldering iron, some solder, wire strippers, electrical tape, and patience == How to setup the DreamPi == Connect the Raspberry Pi to the USB modem, connect that to the phone cable, connect the phone cable to the Dreamcast. Then, connect the Raspberry Pi into your router. Now, download the image, decompress with 7zip (or whatever) and follow the instructions here to flash the image to the SD card: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md Now, insert the SD card into the Pi, and switch it on! == Configuring DreamKey or PlanetWeb == For PlanetWeb, follow the instructions found here under "Configuring the Dreamcast". For DreamKey 3.0. You need to set the ISP number to dial to 555. So, what's the deal with PAL modems? Right, it took me ages to figure this out. U.S modems come in two forms, model "A" modems, and model "B" modems. Model A modems don't draw their power from the telephone line itself, or at least, they don't require it (some USB modems do however!). Model B modems do, and so to do a direct modem-to-modem connection with one of those you need to somehow add power to the connecting phone wire. That's what a "Line Voltage Inducer" does. The best instructions I've found for this are here. But, it gets even more complicated. Generally PAL modems are classed as Model B modems - they require a line voltage. However, I found that not many PAL users had had much luck getting connected, and when I tried, it didn't work for me either, even with a line voltage inducer! Apparently it seems that U.S. Model B modems can suffice with only 9 volts added to the telephone line, but in europe our fussy PAL modems require 18 volts! This is simple enough to do, just build the line voltage inducer as normal, but chain two 9 volt batteries together in series, rather than using just one. == Video instruction == <youtube>VgRLnj2YR3s</youtube> == Pre made kits == [https://www.dreamcastlive.net/shop Dreamcast Live] is selling assembled DreamPi and Voltage Line Inducers. {{DCWiki:Stub}} 47279ba9718e33d40980bc54f249b392b35b3b38 Development 0 2 538 485 2020-01-22T22:27:39Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] adf83e4d518f506c8c82216ee9331ad9a5b90631 545 538 2020-01-22T22:42:57Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Dreamcast optimization]] * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] a4d3185412194dafa3af4b2c1bbaae9998fa3580 GCC-SH4 tips 0 165 546 2020-01-22T22:43:24Z Unknown user 0 Created page with "{{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](..." wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division The Dreamcast is not so good at doing division. ### Integer If you're using integer and want to divide, you're better of using bitshifting. `int result = var1 >> 2; //is the same as var1 / 2 but was faster` `int result = var1 >> 4; // = var1 / 4` `int result = var1 >> 8; // = var1 / 8` ### Float If you're using float, than transforming your division into a multiplication is also faster. `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` 2a7e39794d3cf088a8aae96af594a45d3d32149a 570 546 2020-01-23T16:26:08Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division The Dreamcast is not so good at doing division. ### Integer If you're using integer and want to divide, you're better off using bitshifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, than transforming your division into a multiplication is also faster. `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` edf3e9e2aaacd974c4839f5d88c88b736d798480 Httpd-ack 0 142 547 457 2020-01-23T05:50:49Z Unknown user 0 /* Usage */ wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} == Description == '''Original Release Announcement''' dreamcast gd-rom dumper, requires bba === Usage === [https://www.gotwalls.com/files/httpd-ack.txt https://www.gotwalls.com/files/httpd-ack.txt] {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s using a [[BBA]] over the network to a PC == Source == [https://www.gotwalls.com/ https://www.gotwalls.com/] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} 59b60206a0a7f8e6289f04494604c01d422eac3f 549 547 2020-01-23T06:25:55Z Unknown user 0 /* Usage */ wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} == Description == '''Original Release Announcement''' dreamcast gd-rom dumper, requires bba === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Technical == * Dumps [[GD-ROM]]s using a [[BBA]] over the network to a PC == Source == [https://www.gotwalls.com/ https://www.gotwalls.com/] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} d1cc1920f9606f6bcf68d15bc2896dbb922160bc 550 549 2020-01-23T06:29:40Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} '''httpd-ack''' is software written for the Dreamcast to dump GD-ROMs via a [[Broadband Adapter]] link. === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == GD-R dumping == It is possible to make httpd-ack use the TOC from the IP.BIN at sector 45000 for session 2. The ability to do this is to assist in making it possible to dump GD-R media using a swap disc method, as otherwise the TOC from the old disc would be used when swapping discs with the lid detection switch held down. http://IP/?ipbintoc or http://IP/index.html?ipbintoc The following entry will be logged to the video output to indicate the software is using the TOC from the IP.BIN: get_toc(): using ip.bin for TOC == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Source == [https://www.gotwalls.com/ gotwalls.com] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} 108f39ea12f86e282118ca71121e7954a26ba609 551 550 2020-01-23T06:33:08Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} '''httpd-ack''' is software written for the Dreamcast to dump GD-ROMs via a [[Broadband Adapter]] link. === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == GD-R dumping == It is possible to make httpd-ack use the TOC from the IP.BIN at sector 45000 for session 2. The ability to do this is to assist in making it possible to dump GD-R media using a swap disc method, as otherwise the TOC from the old disc would be used when swapping discs with the lid detection switch held down. http://IP/?ipbintoc or http://IP/index.html?ipbintoc The following entry will be logged to the video output to indicate the software is using the TOC from the IP.BIN: get_toc(): using ip.bin for TOC == Dumping a sector range == track%d and session%d have a dual meaning. If both are >= 100, the value of session%d will act as the start sector, and track%d the end sector, and instead of returning an entire track for download, the software will return a file only containing the specific sector range (session%d through track%d). == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Source == [https://www.gotwalls.com/ gotwalls.com] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} ec9a05d20ddea7def92c24379b0435d831503c30 552 551 2020-01-23T06:34:39Z Unknown user 0 /* GD-R dumping */ wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} '''httpd-ack''' is software written for the Dreamcast to dump GD-ROMs via a [[Broadband Adapter]] link. === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == GD-R dumping == It is possible to make httpd-ack use the TOC from the IP.BIN at sector 45000 for session 2. The ability to do this is to assist in making it possible to dump GD-R media using a [[Dumping GD-ROMs|swap disc method]], as otherwise the TOC from the old disc would be used when swapping discs with the lid detection switch held down. http://IP/?ipbintoc or http://IP/index.html?ipbintoc The following entry will be logged to the video output to indicate the software is using the TOC from the IP.BIN: get_toc(): using ip.bin for TOC == Dumping a sector range == track%d and session%d have a dual meaning. If both are >= 100, the value of session%d will act as the start sector, and track%d the end sector, and instead of returning an entire track for download, the software will return a file only containing the specific sector range (session%d through track%d). == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Source == [https://www.gotwalls.com/ gotwalls.com] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} e1b9d4f8699d14cd6d56618f38c8f24dd8a108ae 561 552 2020-01-23T07:24:52Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} '''httpd-ack''' is software written for the Dreamcast to dump GD-ROMs via a [[Broadband Adapter]] link. === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == Automating dumping == As only one track may be dumped at a time, and the user must sit at the web browser to start dumping the next track, it is recommended to use a script to automate the dumping process if a large number of GD-ROMs will be dumped. A script that can be run on Windows 10, macOS, or Linux is [https://dcemulation.org/dumpcast/viewtopic.php?f=2&t=1666 available]. == GD-R dumping == It is possible to make httpd-ack use the TOC from the IP.BIN at sector 45000 for session 2. The ability to do this is to assist in making it possible to dump GD-R media using a [[Dumping GD-ROMs|swap disc method]], as otherwise the TOC from the old disc would be used when swapping discs with the lid detection switch held down. http://IP/?ipbintoc or http://IP/index.html?ipbintoc The following entry will be logged to the video output to indicate the software is using the TOC from the IP.BIN: get_toc(): using ip.bin for TOC == Dumping a sector range == track%d and session%d have a dual meaning. If both are >= 100, the value of session%d will act as the start sector, and track%d the end sector, and instead of returning an entire track for download, the software will return a file only containing the specific sector range (session%d through track%d). == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Source == [https://www.gotwalls.com/ gotwalls.com] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} b090595c863dc7b2aaf15a40728c5d788d8a3593 Dumping GD-ROMs 0 6 548 208 2020-01-23T06:08:54Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]] or [[Broadband adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). Do not use Dreamshell for dumping GD-ROMs as the ripper software in Dreamshell is unreliable. {| class="wikitable" |+Methods for dumping and types of discs possible to dump |- ! ! Dreamcast<br /> with Broadband Adapter ! Dreamcast<br /> with serial SD card adapter ! Dreamcast<br /> with IDE/CF drive ! Computer<br /> with special DVD-ROM drive |- |Retail GD-ROM |Yes, using [[httpd-ack]] |Yes, using [[SDRip]] |Yes, but [[DreamShell]] dumps unreliable |Yes, using [http://wiki.redump.org/index.php?title=GD-Rom_Dumping_Guide Redump method] |- |GD-R<br />(3-track style) |Yes, with [[System Disc 2]]<br />Yes, with simple swap trick (alternative) |Yes, with [[System Disc 2]]<br />Yes, with simple swap trick (alternative) |Yes, with [[System Disc 2]]<br />Yes, with simple swap trick (alternative)<br />(but [[DreamShell]] dumps unreliable) |No |- |GD-R<br />(>3 tracks with audio) |Yes, with [[System Disc 2]]<br />Yes, with complicated swap trick (alternative) |Yes, but only with [[System Disc 2]] |Yes, with [[System Disc 2]] (but [[DreamShell]] dumps unreliable)<br />Otherwise, requires Broadband Adapter for [[httpd-ack]] |No |- |} 024f50b0a13f3266bff8ee197ad6e29d4bb9850e 555 548 2020-01-23T06:44:04Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]], [[Broadband adapter]], or [[LAN adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). Do not use Dreamshell for dumping GD-ROMs as the ripper software in Dreamshell is unreliable. {| class="wikitable" |+Methods for dumping and types of discs possible to dump |- ! ! Dreamcast<br /> with Broadband/LAN adapter ! Dreamcast<br /> with serial SD card adapter ! Dreamcast<br /> with IDE/CF drive ! Computer<br /> with special DVD-ROM drive |- |Retail GD-ROM |Yes, using [[httpd-ack]] |Yes, using [[SDRip]] |Yes, but [[DreamShell]] dumps unreliable |Yes, using [http://wiki.redump.org/index.php?title=GD-Rom_Dumping_Guide Redump method] |- |GD-R<br />(3-track style) |Yes, with [[System Disc 2]]<br />Yes, with simple swap trick (alternative) |Yes, with [[System Disc 2]]<br />Yes, with simple swap trick (alternative) |Yes, with [[System Disc 2]]<br />Yes, with simple swap trick (alternative)<br />(but [[DreamShell]] dumps unreliable) |No |- |GD-R<br />(>3 tracks with audio) |Yes, with [[System Disc 2]]<br />Yes, with complicated swap trick (alternative) |Yes, but only with [[System Disc 2]] |Yes, with [[System Disc 2]] (but [[DreamShell]] dumps unreliable)<br />Otherwise, requires Broadband Adapter for [[httpd-ack]] |No |- |} 4f57175562b7272cbd486069f18a727e0f7acf2e 556 555 2020-01-23T06:47:08Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]], [[Broadband adapter]], or [[LAN adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). Do not use Dreamshell for dumping GD-ROMs as the ripper software in Dreamshell is unreliable. {| class="wikitable" |+Methods for dumping and types of discs possible to dump |- ! ! Dreamcast<br /> with Broadband/LAN adapter ! Dreamcast<br /> with serial SD card adapter ! Dreamcast<br /> with IDE/CF drive ! Computer<br /> with special DVD-ROM drive |- |Retail GD-ROM |Yes, using [[httpd-ack]] |Yes, using [[SDRip]] |Yes, but [[DreamShell]] dumps unreliable |Yes, using [http://wiki.redump.org/index.php?title=GD-Rom_Dumping_Guide Redump method] |- |GD-R<br />(3-track style) |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick<br />(but [[DreamShell]] dumps unreliable) |No |- |GD-R<br />(>3 tracks with audio) |Yes, with [[System Disc 2]], OR<br />Yes, with complicated swap trick |Yes, but only with [[System Disc 2]] |Yes, but only with [[System Disc 2]]<br />(but [[DreamShell]] dumps unreliable) |No |- |} 32563e047b48cd5da51610dadfe4a9fd9d35454b Licensed games and software 0 144 553 451 2020-01-23T06:36:40Z Unknown user 0 /* List of official Western games */ wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= =List of North American demos= =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= 1b3c05cc93610d5b38977c6bb4ff97d4b8db9799 559 553 2020-01-23T06:57:45Z Unknown user 0 wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= {| class="wikitable" ! North American title ! PAL title |- | |Dreamkey Version 1.0 |- | |Dreamkey Version 1.5 |- | |Dreamkey Version 2.0 |- |PlanetWeb Browser 1.0 | |- |PlanetWeb Browser 2.0 | |- |PlanetWeb Browser 2.62 | |- |PlanetWeb Browser 3.0 |} =List of North American demos= =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= 4b8df16c7660df17e6b2b336be25a34fab54cee1 560 559 2020-01-23T07:14:31Z Unknown user 0 wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title ! Japanese title |- |102 Dalmations - Puppies to the Rescue | | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= {| class="wikitable" ! North American title ! PAL title |- | |Dreamkey Version 1.0 |- | |Dreamkey Version 1.5 |- | |Dreamkey Version 2.0 |- |PlanetWeb Browser 1.0 | |- |PlanetWeb Browser 2.0 | |- |PlanetWeb Browser 2.62 | |- |PlanetWeb Browser 3.0 |} =List of North American demos= {| class="wikitable" ! Title |- |Airforce Delta Demo Disc |- |Army Men - Sarge's Heroes Demo Disc |- |Dead or Alive 2 Demo CD |- |Demolition Racer - No Exit Demo Disc |- |Gauntlet Legends Demo CD |- |Generator, Vol. 1 |- |Generator, Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 3 |- |Official Sega Dreamcast Magazine Vol. 4 |- |Official Sega Dreamcast Magazine Vol. 5 |- |Official Sega Dreamcast Magazine Vol. 6 |- |Official Sega Dreamcast Magazine Vol. 7 |- |Official Sega Dreamcast Magazine Vol. 8 |- |Official Sega Dreamcast Magazine Vol. 9 |- |Official Sega Dreamcast Magazine Vol. 10 |- |Official Sega Dreamcast Magazine Vol. 11 |- |Power Stone Retail Demo Disk |- |Ready 2 Rumble Boxing Demo Disc |- |San Francisco RUSH 2049 Demo CD |- |Sonic Adventure 2 - The Trial |- |Super Magnetic Neo Demo CD |- |Tony Hawk's Pro Skater Demo CD |- |Ultimate Fighting Championship Demo Disc |} =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= 94c69a622155afcab9db001bf59ae5abe187123a Cyber Troopers - Virtual On Oratorio Tangram 0 166 554 2020-01-23T06:37:24Z Unknown user 0 Created page with "[http://voot.sourceforge.net/ VOOT netplay], [https://github.com/quad/voot github with code]" wikitext text/x-wiki [http://voot.sourceforge.net/ VOOT netplay], [https://github.com/quad/voot github with code] ad1682a789e7377b49e719d7b2540f8f9f67bd5b Dreamcast.wiki 0 1 557 247 2020-01-23T06:49:50Z Unknown user 0 /* How To */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] {{DCWiki:About}} == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] * Connect to a [[Modern A/V guide|modern television or display]] {{DCWiki:Software}} {{DCWiki:Hardware}} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} d2f1b914af9b3673137ea1a0e2cce3a01bb68776 Indie games 0 13 562 438 2020-01-23T07:45:36Z Unknown user 0 /* Released */ wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Rizzo's Island]] | 3D platformer | | |- | [[Swirling Blades: Desert Thunder]] | Kazade's choplifter remix ;) | | |- | [[Summoning Signals]] | a strange game | Late 2020 | https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] | "Next-Gen" 2D/3D JRPG | TBD | https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World HD]] |- | [[Bang2 Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black: Flashback 2]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Flashback]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} 544c9cbfe94d461bbe4be1278e1eed8f9b073d03 563 562 2020-01-23T07:51:39Z Unknown user 0 /* Released */ wikitext text/x-wiki == Active Development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Rizzo's Island]] | 3D platformer | | |- | [[Swirling Blades: Desert Thunder]] | Kazade's choplifter remix ;) | | |- | [[Summoning Signals]] | a strange game | Late 2020 | https://www.patreon.com/12dbsoft |- | [[Elysian Shadows]] | "Next-Gen" 2D/3D JRPG | TBD | https://www.elysianshadows.com |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World]] |- | [[Armed Seven]] |- | [[Bang Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Captain Tomaday]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Finding Teddy]] |- | [[Flashback: Quest for Identity]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[FX Unit Yuki: The Henshin Engine]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Magic Pockets]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} 5896431451afc3bcbf1f06b1de0bf6a1b49697e2 564 563 2020-01-23T08:09:07Z Unknown user 0 /* Active Development */ wikitext text/x-wiki == In development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Arcade Racing Legends]] || || || |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || TBD || https://www.elysianshadows.com |- | [[Hypertension: Harmony of Darkness]] | | [[Intrepid Izzy]] || || || |- | [[Midsummer]] || || || |- | [[Non Casual Encounter]] || || || |- | [[Okinawa Rush]] || || || |- | [[Reaperi Cycle]] || || || |- | [[Rizzo Island]] || 3D platformer || || |- | [[Satazius]] || || || |- | [[Shadow Gangs]] || || || |- | [[SLaVE]] |- | [[Summoning Signals]] || a strange game || Late 2020 || https://www.patreon.com/12dbsoft |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || || |- | [[Xenocider]] |- | [[XenoCrisis]] |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World]] |- | [[Armed Seven]] |- | [[Bang Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Captain Tomaday]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Finding Teddy]] |- | [[Flashback: Quest for Identity]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[FX Unit Yuki: The Henshin Engine]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Magic Pockets]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} 9a6352932f2d27221d73980fe87746e7d422a233 565 564 2020-01-23T08:09:23Z Unknown user 0 /* In development */ wikitext text/x-wiki == In development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Arcade Racing Legends]] || || || |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || TBD || https://www.elysianshadows.com |- | [[Hypertension: Harmony of Darkness]] | | [[Intrepid Izzy]] || || || |- | [[Midsummer]] || || || |- | [[Non Casual Encounter]] || || || |- | [[Okinawa Rush]] || || || |- | [[Reaperi Cycle]] || || || |- | [[Rizzo Island]] || 3D platformer || || |- | [[Satazius]] || || || |- | [[Shadow Gangs]] || || || |- | [[SLaVE]] || || || |- | [[Summoning Signals]] || a strange game || Late 2020 || https://www.patreon.com/12dbsoft |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || || |- | [[Xenocider]] || || || |- | [[XenoCrisis]] || || || |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World]] |- | [[Armed Seven]] |- | [[Bang Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Captain Tomaday]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Finding Teddy]] |- | [[Flashback: Quest for Identity]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[FX Unit Yuki: The Henshin Engine]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Magic Pockets]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} 66948aa18ac2f4c99f7a1ae6b2cbe89a8801179e 566 565 2020-01-23T15:50:01Z Unknown user 0 /* In development */ wikitext text/x-wiki == In development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Arcade Racing Legends]] || || || |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || TBD || https://www.elysianshadows.com |- | [[Hypertension: Harmony of Darkness]] | | [[Intrepid Izzy]] || || 2020 || |- | [[Midsummer]] || || || |- | [[Non Casual Encounter]] || || || |- | [[Okinawa Rush]] || || || |- | [[Reaperi Cycle]] || || TBD || |- | [[Rizzo Island]] || 3D platformer || || |- | [[Satazius]] || || || |- | [[Shadow Gangs]] || || || |- | [[SLaVE]] || || || |- | [[Summoning Signals]] || a strange game || Late 2020 || https://www.patreon.com/12dbsoft |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || || |- | [[Xenocider]] || || 2020 || |- | [[XenoCrisis]] || || 2020 || |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World]] |- | [[Armed Seven]] |- | [[Bang Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Captain Tomaday]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Finding Teddy]] |- | [[Flashback: Quest for Identity]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[FX Unit Yuki: The Henshin Engine]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Magic Pockets]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} ca136699c0cf21ada859e71bef2a9f8be7fefd75 567 566 2020-01-23T15:50:30Z Unknown user 0 /* In development */ wikitext text/x-wiki == In development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Arcade Racing Legends]] || || || |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || TBD || https://www.elysianshadows.com |- | [[Hypertension: Harmony of Darkness]] |- | [[Intrepid Izzy]] || || 2020 || |- | [[Midsummer]] || || || |- | [[Non Casual Encounter]] || || || |- | [[Okinawa Rush]] || || || |- | [[Reaperi Cycle]] || || TBD || |- | [[Rizzo Island]] || 3D platformer || || |- | [[Satazius]] || || || |- | [[Shadow Gangs]] || || || |- | [[SLaVE]] || || || |- | [[Summoning Signals]] || a strange game || Late 2020 || https://www.patreon.com/12dbsoft |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || || |- | [[Xenocider]] || || 2020 || |- | [[XenoCrisis]] || || 2020 || |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World]] |- | [[Armed Seven]] |- | [[Bang Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Captain Tomaday]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Finding Teddy]] |- | [[Flashback: Quest for Identity]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[FX Unit Yuki: The Henshin Engine]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Magic Pockets]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} e700e7a60c220063676ba754e4b8a27071a9696c Engine & Library 0 27 571 441 2020-01-23T16:37:09Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) a24772edec37cf605e55ebe94c7f16e61ba7e601 573 571 2020-01-23T19:28:05Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is a copy from the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. * [[libronin]] - an independent development library created by the DreamSNES team ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 6bea1b7c7235e6ca6fe6a58d1b1f7d4c315057c4 Libronin 0 167 572 2020-01-23T19:24:35Z Unknown user 0 Created page with "libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]]..." wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] {{DISPLAYTITLE:libronin}} 71d53842a8940d7372420d311eb068c96c7503a1 574 572 2020-01-23T19:32:06Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] {{DISPLAYTITLE:libronin}} 9130e16b1c109a7762af1b4b68acf76f0a7aee32 575 574 2020-01-23T19:38:56Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 851a50a9d4d41adb17c5dfea416a6ae1442d6992 Libronin 0 167 576 575 2020-01-23T19:39:03Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 98ece54bb1c97b978fcc3466f97de98ca74b0092 Engine & Library 0 27 577 573 2020-01-23T19:41:32Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is an adaptation of the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by Sizious * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. * [[libronin]] - an independent development library created by the DreamSNES team ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 66d914eec9fc422389b767f5dd11d7210e8b7829 KallistiOS 0 21 578 113 2020-01-23T19:43:49Z Unknown user 0 /* Description */ wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Dan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of [[libdream]], the first free developer library for Dreamcast. libdream was also written by Dan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] f183e6349fd9daf48cb6fc8bf9024b2ed718fbab 579 578 2020-01-23T19:45:10Z Unknown user 0 wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Dan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of libdream, the first free developer library for Dreamcast. libdream was also written by Dan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. [http://sourceforge.net/project/showfiles.php?group_id=23791&package_id=76380&release_id=144971 libdream source] == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] 294c7d4bd74cc4ee599ebb9cf798a7e257d6ef00 File:MacCDIRip-0.6.1.zip 6 168 580 2020-01-23T20:40:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this to disassemble CDI images for burning on the Macintosh. PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] b8f36fdd2f22daa3bbb7ab60edd7647ab4d06e83 File:MacCdirip-0.6.3.zip 6 169 581 2020-01-23T20:40:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this to disassemble CDI images for burning on the Macintosh. 64-bit Intel only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] ac8372722172878a0983f617cd0460aa0917db7a File:MacCdirip-OSX-0.6c.zip 6 170 582 2020-01-23T20:40:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this to disassemble CDI images for burning on the Macintosh. PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] b8f36fdd2f22daa3bbb7ab60edd7647ab4d06e83 File:MacDC (de)SCRAMBLER.zip 6 171 583 2020-01-23T20:40:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this to scramble and descramble Dreamcast binaries. Macintosh PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] c6ee7b5c1bec96de78e3d48f14a2799c87439ee1 File:DummyCreator2.zip 6 172 584 2020-01-23T20:40:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this tool to create highly-compressible dummy images to pad out vital data to the outside of a CD. Mac PPC.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 2836f5a73b366fd006f6971ff67b1893749d5fc4 File:MacISOFix.zip 6 173 585 2020-01-23T20:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=fixes ISO images with starting LBA other than 0, making it possible to extract the contents with another program. Mac ppc only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 57d8728e8ed9bb31d806a38d22a32a75fd4c8083 File:MacCDIConverter.zip 6 174 586 2020-01-23T20:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this tool to convert v2 DiscJuggler CDI disk images into v3 images. Mac ppc only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 6d31c542f9da1c4ba2b000ad58fa65e4c2fe233c File:MacDreamTool(i386)-v409.zip 6 175 587 2020-01-23T20:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool 4.09 (i386)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 8d62c257a8577fa361607ce3eb7f6caf31f59ae1 File:MacDreamToolV3.zip 6 176 588 2020-01-23T20:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool 3.0 (ppc)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 2936943e48a8a294ab41b52d6878f94674294929 File:Macpack4.zip 6 177 589 2020-01-23T20:40:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Pack 4 (Mac ppc)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] dd762317bea30047839945de4c73287332472b0e File:MakeIP.BIN(MacClassic).zip 6 178 590 2020-01-23T20:40:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=IP.BIN creator for Mac Classic ppc.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] f6a63e9271cc2780644fd5a25932e08f5b3b9b74 File:MDTS122.tar.gz 6 179 591 2020-01-23T20:40:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool Services 1.2.2 including DreamSNES ROMs List creator. PPC Mac.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 102e508e57d0c7b1a18331721b3a8f1b444efdd8 File:MDTv4.zip 6 180 592 2020-01-23T20:40:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool 4.03, Mac ppc only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] f82165a9b575e6eaf112e53ba8d430e98224feec File:MacCDIRip-0.6.2.zip 6 181 593 2020-01-23T20:49:45Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=use this to disassemble CDI images for burning on the Macintosh. PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] b8f36fdd2f22daa3bbb7ab60edd7647ab4d06e83 File:DC Serial Cable on Mac.sit 6 182 594 2020-01-23T20:49:45Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=OS9 Classic tools and tutorial on how to connect a DC serial cable to an appropriate Macintosh.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] c0ad21047ad1e5f2db336f4d1d2cf4b7f8b80ac0 File:Mdt2PPC.tgz 6 183 595 2020-01-23T20:49:45Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool 2.1. Mac PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] f5b54f4f0a275d6a53d2bd0eb96ae179f6c2057d File:Mdt12.tgz 6 184 596 2020-01-23T20:49:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool 1.2. Mac PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 51046638364aaff664d18fc37d3699ab6312bb85 File:MDT22.tgz 6 185 597 2020-01-23T20:49:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool 2.2. Mac PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 07f186b690dfb05886755affaeea08ca4e4c1eab File:MDTSPPC.tgz 6 186 598 2020-01-23T20:49:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool Services 1.0 including DreamSNES ROMs List creator. Mac PPC only.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] e515ddc456649b2705d06f17801b4945540e1f7b File:Mkisofs-binary-OSXPB.tgz 6 187 599 2020-01-23T20:49:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=mkisofs for Mac PPC.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 5906fc6ed35c12f862bf39e643222e853f2a6f92 File:Cdrecord-power-macintosh-rhapsody.gz 6 189 600 2020-01-23T21:08:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdrecord build for PPC Mac}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] d07bb06b7a74010dd659a922744491bd13dd951b File:Isofix13 mac-i386.tar.gz 6 188 601 2020-01-23T21:08:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=isofix 1.3 for Mac intel}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] f62d48aaee02da6f8032d69ec69c3f881953926e File:Cdrtools-i386-apple-macosx10.8.0.tar.gz 6 190 602 2020-01-23T21:08:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdrecord build for OSX intel}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 4059c9caca78fe0dbdc0297201f3bee4ed85a7cb File:Mkisofs i386.zip 6 191 603 2020-01-23T21:08:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=mkisofs Mac 32-bit}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 570f6b3604f4d6aced35035263a56e376147b23b File:Scramble i386.zip 6 192 604 2020-01-23T21:08:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Binary scrambler for Intel Mac}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] 69c853c0162165cc957e988b2e60c82f5715dbcc File:MacDreamToolServices(i386)-v133.zip 6 193 605 2020-01-23T21:08:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Mac Dream Tool Services 1.3.3. Intel Macs.}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Mac]] f63c70d5151af2ceb2a13f14528c147e54b7891a Mac tools 0 194 606 2020-01-23T21:19:56Z Unknown user 0 Created page with "This page contains a list of Mac tools. Needs cleaning up, downloads need clear identification of binary type for each (classic, ppc, x86, x86_64) =Main tools= * :File:Cdrt..." wikitext text/x-wiki This page contains a list of Mac tools. Needs cleaning up, downloads need clear identification of binary type for each (classic, ppc, x86, x86_64) =Main tools= * [[:File:Cdrtools-i386-apple-macosx10.8.0.tar.gz|CDRTools{cdrecord} (i386 Intel)]] - A package of freeware unix command line programs for burning and manipulating cds. Created by Jorg Schilling under GNU GPL. * [[:File:Cdrecord-power-macintosh-rhapsody.gz|CDRecord (PowerPC)]] - A freeware Mac OSX unix command line program for burning cds. Created by Jorg Schilling under the GNU GPL. * [[:File:MacCdirip-0.6.3.zip|CDIRip 0.6.3]] - use this to disassemble CDI images for burning on the Macintosh. 64-bit Intel only. * [[:File:MacCDIRip-0.6.2.zip|CDIRip 0.6.2]] - use this to disassemble CDI images for burning on the Macintosh. PPC only. * [[:File:MacCDIRip-0.6.1.zip|CDIRip 0.6.1]] - an older version of the above tool. * [[:File:MacCdirip-OSX-0.6c.zip|CDIRip 0.6c]] - an even older version of the above tool. * [[:File:Isofix13 mac-i386.tar.gz|ISOFix - (i386 Intel)]] - fixes ISO images with starting LBA other than 0, making it possible to extract the contents with another program. * [[:File:MacISOFix.zip|ISOFix]] - fixes ISO images with starting LBA other than 0, making it possible to extract the contents with another program. * [http://dcemulation.org/gbadcdev/dc/Weepel'sNewSelfbooter.dmg Weepel's New Selfbooter] - An easy-to-use OS X utility used for creating self-booting image files from Plain File Archives. An alternative for MDT. Created by Weepel. [URL dead] * [[:File:MacCDIConverter.zip|CDI Converter]] - use this tool to convert v2 DiscJuggler CDI disk images into v3 images. * [[:File:Mkisofs i386.zip|mkisofs 1.13 (i386 Intel)]] - use this to create ISO files for a data track on a Dreamcast disk. * [[:File:Mkisofs-binary-OSXPB.tgz|mkisofs 1.13]] - PPC - use this to create ISO files for a data track on a Dreamcast disk. * [[:File:MakeIP.BIN(MacClassic).zip|Make IP.BIN]] - for classic MacOS, this program allows you to create custom bootsectors for Dreamcast disks. * [[:File:Scramble i386.zip|(de)Scrambler (i386 Intel)]] - use this to scramble and descramble Dreamcast binaries. * [[:File:MacDC (de)SCRAMBLER.zip|(de)Scrambler]] - PPC - use this to scramble and descramble Dreamcast binaries. * [[:File:DummyCreator2.zip|Dummy Creator 2]] - use this tool to create highly-compressible dummy images to pad out vital data to the outside of a CD. =Mac Dream Tool= cedd0520d5169f27fb608ba04c6bff0247dea004 607 606 2020-01-23T21:30:30Z Unknown user 0 wikitext text/x-wiki This page contains a list of mostly old Mac tools. Needs cleaning up, downloads need clear identification of binary type for each (classic, ppc, x86, x86_64) =Main tools= * [[:File:Cdrtools-i386-apple-macosx10.8.0.tar.gz|CDRTools{cdrecord} (i386 Intel)]] - A package of freeware unix command line programs for burning and manipulating cds. Created by Jorg Schilling under GNU GPL. * [[:File:Cdrecord-power-macintosh-rhapsody.gz|CDRecord (PowerPC)]] - A freeware Mac OSX unix command line program for burning cds. Created by Jorg Schilling under the GNU GPL. * [[:File:MacCdirip-0.6.3.zip|CDIRip 0.6.3]] - use this to disassemble CDI images for burning on the Macintosh. 64-bit Intel only. * [[:File:MacCDIRip-0.6.2.zip|CDIRip 0.6.2]] - use this to disassemble CDI images for burning on the Macintosh. PPC only. * [[:File:MacCDIRip-0.6.1.zip|CDIRip 0.6.1]] - an older version of the above tool. * [[:File:MacCdirip-OSX-0.6c.zip|CDIRip 0.6c]] - an even older version of the above tool. * [[:File:Isofix13 mac-i386.tar.gz|ISOFix - (i386 Intel)]] - fixes ISO images with starting LBA other than 0, making it possible to extract the contents with another program. * [[:File:MacISOFix.zip|ISOFix]] - fixes ISO images with starting LBA other than 0, making it possible to extract the contents with another program. * [http://dcemulation.org/gbadcdev/dc/Weepel'sNewSelfbooter.dmg Weepel's New Selfbooter] - An easy-to-use OS X utility used for creating self-booting image files from Plain File Archives. An alternative for MDT. Created by Weepel. [URL dead] * [[:File:MacCDIConverter.zip|CDI Converter]] - use this tool to convert v2 DiscJuggler CDI disk images into v3 images. * [[:File:Mkisofs i386.zip|mkisofs 1.13 (i386 Intel)]] - use this to create ISO files for a data track on a Dreamcast disk. * [[:File:Mkisofs-binary-OSXPB.tgz|mkisofs 1.13]] - PPC - use this to create ISO files for a data track on a Dreamcast disk. * [[:File:MakeIP.BIN(MacClassic).zip|Make IP.BIN]] - for classic MacOS, this program allows you to create custom bootsectors for Dreamcast disks. * [[:File:Scramble i386.zip|(de)Scrambler (i386 Intel)]] - use this to scramble and descramble Dreamcast binaries. * [[:File:MacDC (de)SCRAMBLER.zip|(de)Scrambler]] - PPC - use this to scramble and descramble Dreamcast binaries. * [[:File:DummyCreator2.zip|Dummy Creator 2]] - use this tool to create highly-compressible dummy images to pad out vital data to the outside of a CD. =Mac Dream Tool= Mac Dream Tool is a program that allows users to create Dreamcast CDs on their computers running Mac OS X. You can put multiple emulators, games, demos, applications, and so forth all on one disk using SBI files; you can also create single-program discs using SBI files or plain binaries. Created by [gbadcdev.dcemulation.org I.M.Weasel]. ===Intel 32-bit=== *[[:File:MacDreamTool(i386)-v409.zip|Mac Dream Tool 4.09]] ===OS X PowerPC=== *[[:File:MDTv4.zip|Mac Dream Tool 4.03]] *[[:File:MacDreamToolV3.zip|Mac Dream Tool 3.0]] *[[:File:MDT22.tgz|Mac Dream Tool 2.2]] *[[:File:Mdt2PPC.tgz|Mac Dream Tool 2.1]] *[[:File:Mdt12.tgz|Mac Dream Tool 1.2]] =Mac Dream Tool Services= Mac Dream Tool Services is a program with tools that allow you to perform certain Dreamcast-related tasks such as converting PNG images to the MR format for custom bootsector logo insertion, injecting a .mr image into a ip.bin binary bootstrap file, creating Selfboot Inducer packages, inserting a bootsector (IP.BIN) into a CDI image, and a ROM renamer for SMS ROMs for use with SMSPlus screenshots. The DreamSnes ROMS.LST creator has been removed in the 1.3.3 Version. ===Intel (i386) Macs (10.4/5/6 & maybe above)=== *[[File:MacDreamToolServices(i386)-v133.zip|Mac Dream Tool Services 1.3.3]] ===PowerPC Macs=== This version includes the ROMs list creator file for use with DreamSNES. *[[:File:MDTS122.tar.gz|Mac Dream Tool Services 1.2.2]] *[[:File:MDTSPPC.tgz|Mac Dream Tool Services 1.0]] =Mac Pack= The Mac Pack is a collection of tools used for creating Dreamcast disks manually on Mac. This is not for new users, as these tools require an understanding of the layout of a Dreamcast disk. *[[:File:Macpack4.zip|Mac Pack 4]] =Development Tools= *[[:File:DC Serial Cable on Mac.sit|Mac Classic Serial Link]] - Mac OS 9 tools and tutorial for connecting a Dreamcast serial cable to a Macintosh. 89c9d3a0e27d5b17cb2e3df6039a3533ac4478f5 DCWiki:Software 4 81 608 558 2020-01-23T21:34:32Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} ae3054ea3689814bc8895776371ec37a1de824b2 Old tools 0 195 609 2020-01-23T21:40:01Z Unknown user 0 Created page with "This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage." wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. 708a0c22bf812b2d1cf1c76ab82bfef6d36683e4 File:Gdibuilder12 cmd.zip 6 196 610 2020-01-23T22:26:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=gdibuilder 1.2 cmd line Windows}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 25ff75a48f5e1a5c3a9c486b5ced9999773ec29c File:GDEMU FW COLLECTION.rar 6 197 611 2020-01-23T22:26:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=All GDEMU historical firmwares until 5.15.0}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 84fa6b1df06ff741fbfde194a0be72c32127f672 File:GDEMU SD.rar 6 198 612 2020-01-23T22:26:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDEmu SD Card Maker 24-04-2018}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 7213f60c43fea90fd6cd27b8e895b62f4c976f50 File:Gdibuilder12 win.zip 6 199 613 2020-01-23T22:26:29Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=gdibuilder 1.2 GUI Windows}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] a3035115870891506a033851c47dff188cd9139f File:Gdmenu(23-8-2014).zip 6 200 614 2020-01-23T22:26:29Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDMenu v0.01 2014-08-23}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] fdb604bcb435112d9aaf7c5de7061d15556d457b File:Gditools 20150714 exe.rar 6 201 615 2020-01-23T22:26:29Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=gditools 20150714 exe}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 1f5365cd753d19699229041d38a586bf93fa7426 File:GDmenu v0.2(15-09-2014) bin only.rar 6 203 616 2020-01-23T22:26:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDmenu v0.2(15-09-2014) bin only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] d1f2bd98822bd161ec08619d9bbb0bc90c4ef3d9 File:GDMENU Builder Mono.rar 6 202 617 2020-01-23T22:26:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDMenu Builder EXE for Linux (Mono)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 934abd8aa133f94d0d6a1cc24f75e3a4ac4b0300 File:GDmenu v0.3(17-10-2014) bin only.rar 6 204 618 2020-01-23T22:26:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDmenu v0.3(17-10-2014) bin only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 9f59dee9e80907173fa9d7894ce6170667d3ae14 File:GDmenu v0.4(08-02-2015).zip 6 205 619 2020-01-23T22:26:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDmenu v0.4(08-02-2015)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] fcf6b7d17d4aa0779b54ea74593a891d4d4b8db6 File:GDmenu v0.5.1(14-06-2015) bin only.rar 6 206 620 2020-01-23T22:26:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDmenu v0.5.1(14-06-2015) bin only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 73776e34464f0f1912fd2d77d7d83ebbe249772f File:GDmenu v0.5.2(14-07-2015).zip 6 207 621 2020-01-23T22:26:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDmenu v0.5.2(14-07-2015)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 93b08f59aefdd701481150c28bdb12ca4dc59bf8 File:GDmenu v0.6(24-08-2016).zip 6 208 622 2020-01-23T22:26:31Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDmenu v0.6(24-08-2016)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] 72e75b2d144fb8437c600f4918834dc8f9d8855f File:RebuildGDI.rar 6 209 623 2020-01-23T22:26:31Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GDI Rebuilder}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:GDEMU]] adf2a05f96600f5f2a7f964fbf1c0dad5e34ffd7 GDEMU 0 164 624 537 2020-01-23T22:30:58Z Unknown user 0 /* Tools */ wikitext text/x-wiki The GDEMU a [[GD-ROM]] disk drive replacement. '''Offical link''' : https://gdemu.wordpress.com == Usage == ''This content has been copied from the official source'' GDEMU is compatbile with VA1 model Dreamcasts from all regions IMPORTANT: VA2 model is not compatible. Mating GDEMU with VA0 model mainboard is possible but will cause permanent damage to the device. See installation instructions. '''Supported image types:''' * GDI (for GD-ROMs) * CDI * CCD+IMG+SUB * MDS+MDF * ISO (as data carriers for homebrew) IMPORTANT: Recently some new dumping groups have been releasing GDIs dumped with PC CD-ROM drive using so-called “swap method”. Technically there is nothing wrong with it except for slightly different “offset” on audio tracks compared to what Dreamcast drive would produce, nothing you’d even notice. But they’ve changed the way track starting address is calculated and as a result all games that have digital audio, or data split beyond track #3, will not work properly. This is not a GDEMU issuse and there is no fix planned for this – avoid such dumps. '''Image layout:''' * Every image must be put in a separate folder * Folder names must consist of: ** 2 digits for 01 to 99 ** 3 digits up to 999 ** 4 digits up to 9999 *All file names must be in DOS 8.3 format *The main image file must be called “disc” with appropriate extension IMPORTANT: Long filenames are not supported, neither are names containing non-ASCII characters. You can, however, put a file named with the game title in each folder for better organization, even if it’s a long name – it will be ignored by GDEMU. An example of correct filenames for GDI image: -- track01.bin -- track03.bin -- disc.gdi -- track02.raw == Tools == *[[GDMenu]] - A homebrew program that let you choose between all your games/program on your SD card. *[[:File:GDEMU FW COLLECTION.rar|GDEmu firmware files to version 5.15.0]] *[[:File:GDEMU SD.rar|GDEmu SD Card Maker 24-04-2018]] *[[:File:Gdibuilder12 cmd.zip|gdibuilder 1.2 cmd line Windows]] *[[:File:Gdibuilder12 win.zip|gdibuilder 1.2 GUI Windows]] *[[:File:Gditools 20150714 exe.rar|gditools 20150714 exe]] *[[:File:GDMENU Builder Mono.rar|GDMenu Builder for Linux (with Mono)]] *[[:File:Gdmenu(23-8-2014).zip|GDMenu v0.01 2014-08-23]] *[[:File:GDmenu v0.2(15-09-2014) bin only.rar|GDmenu v0.2(15-09-2014) bin only]] *[[:File:GDmenu v0.3(17-10-2014) bin only.rar|GDmenu v0.3(17-10-2014) bin only]] *[[:File:GDmenu v0.4(08-02-2015).zip|GDmenu v0.4(08-02-2015)]] *[[:File:GDmenu v0.5.1(14-06-2015) bin only.rar|GDmenu v0.5.1(14-06-2015) bin only]] *[[:File:GDmenu v0.5.2(14-07-2015).zip|GDmenu v0.5.2(14-07-2015)]] *[[:File:GDmenu v0.6(24-08-2016).zip|GDmenu v0.6(24-08-2016)]] *[[:File:RebuildGDI.rar|GDI Rebuilder]] 8cab989066d7b4ebe2ea8423a13bb1ac75995130 File:Cdi4dc 01b.zip 6 210 625 2020-01-23T22:44:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdi4dc v0.1b by SiZiOUS}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8e47cf1b14c5ac9934ddb31db2d7a1a42877da5b File:Cdi4dc 02b.zip 6 211 626 2020-01-23T22:44:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdi4dc v0.2b by SiZiOUS}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1e855b6acec53ad6c4595c7e1d15153907259fea File:Cdi4dc 02b linux.zip 6 212 627 2020-01-23T22:44:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdi4dc v0.2b for Linux by SiZiOUS}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} fac2d7b662943daaac8b732efca849576c05218d File:Cdi4dc 03b.zip 6 213 628 2020-01-23T22:44:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdi4dc v0.3b by SiZiOUS}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b6282188f7fd7a61b519256a34e2095106ff0789 File:Cdi4dc 02b linux colors.zip 6 214 629 2020-01-23T22:44:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=cdi4dc v0.2b for Linux with colors by SiZiOUS}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b5692c7516c1161e8bed0199943fa10f0d16041c Cdi4dc 0 215 630 2020-01-23T22:44:50Z Unknown user 0 Created page with "*[[:File:Cdi4dc 01b.zip|thumb|cdi4dc v0.1b by SiZiOUS]] *[[:File:Cdi4dc 02b.zip|thumb|cdi4dc v0.2b by SiZiOUS]] *:File:Cdi4dc 02b linux.zip|thumb|cdi4dc v0.2b for Linux by S..." wikitext text/x-wiki *[[:File:Cdi4dc 01b.zip|thumb|cdi4dc v0.1b by SiZiOUS]] *[[:File:Cdi4dc 02b.zip|thumb|cdi4dc v0.2b by SiZiOUS]] *[[:File:Cdi4dc 02b linux.zip|thumb|cdi4dc v0.2b for Linux by SiZiOUS]] *[[:File:Cdi4dc 02b linux colors.zip|thumb|cdi4dc v0.2b for Linux with colors by SiZiOUS]] *[[:File:Cdi4dc 03b.zip|thumb|cdi4dc v0.3b by SiZiOUS]] 02a852bc0df6f49d7258acb32673e4771f4f50ea 631 630 2020-01-23T22:45:10Z Unknown user 0 wikitext text/x-wiki *[[:File:Cdi4dc 01b.zip|cdi4dc v0.1b by SiZiOUS]] *[[:File:Cdi4dc 02b.zip|cdi4dc v0.2b by SiZiOUS]] *[[:File:Cdi4dc 02b linux.zip|cdi4dc v0.2b for Linux by SiZiOUS]] *[[:File:Cdi4dc 02b linux colors.zip|cdi4dc v0.2b for Linux with colors by SiZiOUS]] *[[:File:Cdi4dc 03b.zip|cdi4dc v0.3b by SiZiOUS]] 38ed8651d7a0645dc9f85c4cae65a88ac39f0cea Hardware overview 0 38 632 515 2020-01-24T00:40:18Z Unknown user 0 wikitext text/x-wiki *'''CPU''': Hitachi SuperH SH7750 SH-4 RISC CPU @ 200MHz **200 MHz/360 MIPS at 3.3V I/O, 1.8V internal **16 x 32-bit general purpose registers **32 x 32-bit single-precision floating point registers **16-bit fixed instruction length for high code density **5 stage pipeline **On-chip cache, 8KB instruction and 16KB data *'''GPU''': NEC PowerVR2 with 8MB of [[VRAM|texture memory]] *'''Sound''': Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memory''': 16MB system memory *'''Storage''': [[GD-ROM drive]] *'''Network''': 33.6K or 56K [[Modem|modem]] c7e0f179ec80a1140bf532d6b41d40b2d0a2af1f File:Bbrip v1.2.zip 6 216 633 2020-01-24T00:53:02Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=BBRip v1.2 software (obsolete)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 54765450796988fa03be0501daa2fe1ea1aa94a1 Broadband adapter 0 5 634 528 2020-01-24T00:54:58Z Unknown user 0 /* Tools */ wikitext text/x-wiki The Dreamcast '''Broadband Adapter''' ('''HIT-400''' or '''HIT-401'''), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139 chip and connects to the G2 bus. It was released in Japan and in the United States, but not in PAL regions, although some PAL game software does work with it. The Broadband adapter is a somewhat rare peripheral, but is useful for playing networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .cdi and .elf files over the BBA. Mostly intended for homebrew developement. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (use httpd-ack instead) {{DCWiki:Stub}} cb345a7920ad3aa410d97b12da2b66120ae792bd File:E-selfbt.zip 6 217 635 2020-01-24T00:57:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=The very original Echelon selfboot toolkit}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0a534ef223585a8f470851b63fc6e5c1e23dc8cc Old tools 0 195 636 609 2020-01-24T00:57:42Z Unknown user 0 wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. [[:File:E-selfbt.zip|The very original Echelon selfboot toolkit]] 85e68d81cb1bb22191c66c292b630f54e3c01e9a 641 636 2020-01-24T01:22:46Z Unknown user 0 wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|The very original Echelon selfboot toolkit]] *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[File:Makesort.zip|makesort]] - Converts isobuster sort files to cdrecord format 3dfeabad973c71429de788b8f6849b535c3320db 642 641 2020-01-24T01:22:59Z Unknown user 0 wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|The very original Echelon selfboot toolkit]] *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Converts isobuster sort files to cdrecord format 42cb93fbb80aadc0436e226bef7673ed4a78779a 656 642 2020-01-24T01:52:01Z Unknown user 0 wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|The very original Echelon selfboot toolkit]] *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) 3b61bdc6d132c3af5d12b74545cd16633229c149 657 656 2020-01-24T01:52:21Z Unknown user 0 wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) b6cd2c02a6adec965112dbf6de1ae60acee70422 File:Cdmage.zip 6 218 637 2020-01-24T01:02:04Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=CDMage 1.01.5 and 1.02.1b}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 199c9216b1685602bd3de229b83552484ccf2377 File:Ipbin4win.zip 6 219 638 2020-01-24T01:07:32Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=IPBIN4WIN 0.8b by Dextrose}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 5c7e522c5114b24af8b51b9c8c68ef1e5bd65673 File:Ip2post.rar 6 220 639 2020-01-24T01:09:21Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=IP2POST utility for Dumpcast}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 022e3a251a81a1371b2a09bbdca2984aa0fc7da7 File:Makesort.zip 6 221 640 2020-01-24T01:11:57Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Converts isobuster sort files to cdrecord format}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a98b73405e1867ad75b8cd55bc57349edf816365 File:Httpd-ack-20070511.zip 6 222 643 2020-01-24T01:32:43Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack 20070511 elf + cdi}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f43aca9d8776067f5530c1ab7171c6e1a410274f File:Httpd-ack-20070430.zip 6 223 644 2020-01-24T01:32:43Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack 20070430 elf + cdi}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2d6941e7472df7016e434a5173e2899b1add418a File:Httpd-ack-20070624.zip 6 224 645 2020-01-24T01:32:43Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack 20070624 elf only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ba042065a32a6b6ba26649e2094569dc5f8f3865 File:Httpd-ack-20070720.zip 6 225 646 2020-01-24T01:32:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack 20070720 elf + cdi}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c6630651c5cc4125bb32b8d4cb9aea1e40882888 File:Httpd-ack-gdr-test.zip 6 226 647 2020-01-24T01:32:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack gdr-test BETA from 20070625 elf only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8d8e41501cdaa54bb1da310ebca371fa9d0dac9b File:Httpd-ack-20071123.zip 6 227 648 2020-01-24T01:32:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack 20071123 elf + cdi}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 37c20ea33c008b6f9d6f893e7b90a4e011bade83 File:Httpd-ack-gdr-test2.zip 6 228 649 2020-01-24T01:32:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack gdr-test BETA 2 from 20070626 elf only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d9f4d23c79acd418b64e0e09b3aae740ba62752f File:Httpd-ack-gdr-test3.zip 6 229 650 2020-01-24T01:32:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=httpd-ack gdr-test BETA 3 from 20070626 elf only}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 822f529a3016d4bc4c4722a253dab0025b629289 Httpd-ack 0 142 651 561 2020-01-24T01:37:43Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 7, 2018 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} '''httpd-ack''' is software written for the Dreamcast to dump GD-ROMs via a [[Broadband Adapter]] link. === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == Automating dumping == As only one track may be dumped at a time, and the user must sit at the web browser to start dumping the next track, it is recommended to use a script to automate the dumping process if a large number of GD-ROMs will be dumped. A script that can be run on Windows 10, macOS, or Linux is [https://dcemulation.org/dumpcast/viewtopic.php?f=2&t=1666 available]. == GD-R dumping == It is possible to make httpd-ack use the TOC from the IP.BIN at sector 45000 for session 2. The ability to do this is to assist in making it possible to dump GD-R media using a [[Dumping GD-ROMs|swap disc method]], as otherwise the TOC from the old disc would be used when swapping discs with the lid detection switch held down. http://IP/?ipbintoc or http://IP/index.html?ipbintoc The following entry will be logged to the video output to indicate the software is using the TOC from the IP.BIN: get_toc(): using ip.bin for TOC == Dumping a sector range == track%d and session%d have a dual meaning. If both are >= 100, the value of session%d will act as the start sector, and track%d the end sector, and instead of returning an entire track for download, the software will return a file only containing the specific sector range (session%d through track%d). == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Source == [https://www.gotwalls.com/ gotwalls.com] == Historical builds == *[[:File:Httpd-ack-20080711.zip|httpd-ack 20080711 elf + cdi]] *[[:File:Httpd-ack-20071123.zip|httpd-ack 20071123 elf + cdi]] *[[:File:Httpd-ack-20070720.zip|httpd-ack 20070720 elf + cdi]] *[[:File:Httpd-ack-gdr-test3.zip|httpd-ack gdr-test BETA 3 from 20070626 elf only]] *[[:File:Httpd-ack-gdr-test2.zip|httpd-ack gdr-test BETA 2 from 20070626 elf only]] *[[:File:Httpd-ack-gdr-test.zip|httpd-ack gdr-test BETA 1 from 20070625 elf only]] *[[:File:Httpd-ack-20070624.zip|httpd-ack 20070624 elf only]] *[[:File:Httpd-ack-20070511.zip|httpd-ack 20070511 elf + cdi]] *[[:File:Httpd-ack-20070430.zip|httpd-ack 20070430 elf + cdi]] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} 482f4c5275a39bd9d97187ffb8ea912860a2b56e File:Dcdump.zip 6 230 652 2020-01-24T01:46:15Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=dcdump.sh bash script for dumping GD-ROMs with httpd-ack}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f506ca7215a512e70922117cd3d501aa8eebfbe7 File:Dccuegen.zip 6 231 653 2020-01-24T01:46:15Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=quick and crude cuesheet generator for dreamcast dumps}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 281cc371f3db660c17338247fafa07862b9a3249 File:Gdhack.zip 6 232 654 2020-01-24T01:46:15Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GD hacking utilities (cdda, dahack, hack3)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d43f7d6013adb3983ddf5134b8db85ba40879010 File:Gdhack4.zip 6 233 655 2020-01-24T01:46:16Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=GD hacking utility (hack4)}} |date=2020-01-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a8808024f82fdf83b648c3973c98152589b4c243 GCC-SH4 tips 0 165 659 570 2020-01-24T17:18:08Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles. `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` 6b2e871b14083a2cad18c93cb661b6e86829e28b 661 659 2020-01-24T17:24:45Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly instructions</ref> `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> e7664309f2c5a6c506618ea394e77d749c875fcf 662 661 2020-01-24T17:25:39Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles <ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly instructions</ref> `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> 3558fcfd5776bb0f99f125fbbed969fdd73a3367 663 662 2020-01-24T17:29:24Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles <ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly instructions</ref> `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> 71b04ab5db499c4132a15fbb4d5621c4f6c166f0 664 663 2020-01-24T17:31:30Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles <ref></ref> `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> 6d4e79711971ff5914db799304c691bbd5b5348c 665 664 2020-01-24T17:31:47Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, Mrneo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but was faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles. `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> ff0337624f127a104cb26c92512b634be2c06447 668 665 2020-01-24T17:39:52Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but way faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles. `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> d8e7e603f54976dc1dffa54c8d755f16c6456f5a 669 668 2020-01-24T17:40:06Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ## Dan Potter's GCC-SH4 tips ### Use local variables. Global variables are slow - to retrieve the value, the SH4 typically must execute: `mov.l L2,r1` `mov.l @r1,r1` Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ### Write small functions. We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ### Use struct copies (instead of copying individual elements of a struct). GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. ## Division Using division on the Dreamcast is very costly. ### Integer If you're using integer and want to divide by a power of two, you're better off using bit shifting. `int result = var1 >> 1; //is the same as var1 / 2 but way faster` `int result = var1 >> 2; // = var1 / 4` `int result = var1 >> 3; // = var1 / 8` ### Float If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles. `float result = var1 * 0.5; // same as / 2 but way faster` `float result = var1 * 0.25; // same as / 4 but way faster` `float result = var1 * 0.1; // same as / 10 but way faster` ==References== <references/> f7ca2b6106d6f8c28faf3970f79893c4ecd64f24 670 669 2020-01-24T19:05:55Z Unknown user 0 Markdown => WikiText wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and **function parameters are even faster because the first four integers parameters are passed in r4-r7 and first eight floating-point parameters in fr4-fr11**. ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> d183f8408999f9e0e7918b6720c49d60b5f0100b 671 670 2020-01-24T19:11:27Z Unknown user 0 wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 4242278fc8329e4faffb4ddd52dae73a2b652b83 675 671 2020-01-24T19:19:12Z Unknown user 0 BBHoodsta moved page [[Dreamcast optimization]] to [[GCC-SH4 tips]]: Title was too general. Content was related to GCC and SH4 optimizations. Its already under Optimizations so no need to add that to the title wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplying takes 3 cycles while division takes around 13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 4242278fc8329e4faffb4ddd52dae73a2b652b83 Talk:Divide performance 1 235 660 2020-01-24T17:18:45Z Unknown user 0 Created page with "I think we can delete this in favor of https://dreamcast.wiki/Dreamcast_optimization ~~BBHoodsta" wikitext text/x-wiki I think we can delete this in favor of https://dreamcast.wiki/Dreamcast_optimization ~~BBHoodsta 68d239d5a59b23ec418c858cdd63eb776666269f Hardware Tests 0 150 666 474 2020-01-24T17:33:59Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Hardware tests serve as living documentation of the Dreamcast hardware. They can be used to verify that behavior matches expectations, or take timing measurements. They can be burnt to a CD and run on retail Dreamcast systems to prove that the test is correct, or they can be used to test clone systems and emulators for correctness. ## Arm7Wrestler DC * Download : [https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz](https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz) * Source Code : [https://github.com/snickerbockers/dc-arm7wrestler](https://github.com/snickerbockers/dc-arm7wrestler) * Purpose : Tests for CPU bugs in the AICA's ARM7DI. ==References== <references/> fa86e00ed10f3c5a30d0b54c508c7855b90c3f88 667 666 2020-01-24T17:34:11Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} Hardware tests serve as living documentation of the Dreamcast hardware. They can be used to verify that behavior matches expectations, or take timing measurements. They can be burnt to a CD and run on retail Dreamcast systems to prove that the test is correct, or they can be used to test clone systems and emulators for correctness. ## Arm7Wrestler DC * Download : [https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz](https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz) * Source Code : [https://github.com/snickerbockers/dc-arm7wrestler](https://github.com/snickerbockers/dc-arm7wrestler) * Purpose : Tests for CPU bugs in the AICA's ARM7DI. 947e77e078b225977963ff190ba31e9824870402 Development 0 2 672 545 2020-01-24T19:14:42Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 178dcdcfc71c997dbf75adaf8202706eb77bf6cd 673 672 2020-01-24T19:15:03Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Dreamcast Optimization]] * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 3b5348cf9f7cebc3ebc9049fbbb7e67730ae4b82 674 673 2020-01-24T19:15:15Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[Dreamcast optimization]] * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] a4d3185412194dafa3af4b2c1bbaae9998fa3580 Dreamcast optimization 0 236 676 2020-01-24T19:19:12Z Unknown user 0 BBHoodsta moved page [[Dreamcast optimization]] to [[GCC-SH4 tips]]: Title was too general. Content was related to GCC and SH4 optimizations. Its already under Optimizations so no need to add that to the title wikitext text/x-wiki #REDIRECT [[GCC-SH4 tips]] 3ec5547a956fbcf20876d359d9ff1e2bbb483208 Development 0 2 677 674 2020-01-24T19:19:45Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Divide performance]] * [[Dan Potter's notes]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 178dcdcfc71c997dbf75adaf8202706eb77bf6cd 678 677 2020-01-24T19:25:25Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 02ac1d4ba43d00771e568bf3eb2e1d114482b651 688 678 2020-01-29T00:04:10Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] f1160e42f2ab6eff510c0185d1bc2eb86c3f1e73 GCC-SH4 tips 0 165 679 675 2020-01-24T20:10:10Z Unknown user 0 wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division takes around 13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplying only takes 3 cycles. <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 993071e00531268e248315d7b8f1554ce2b0f60d 680 679 2020-01-24T20:12:40Z Unknown user 0 wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles. <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 8249461f323975c7c9a568801df1ea9bc283d0e7 681 680 2020-01-24T20:13:12Z Unknown user 0 wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref>''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 2ef5c43e7cf206c3c4b055781d4aa464ff8e605f 682 681 2020-01-24T20:21:14Z Unknown user 0 /* Division */ wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <code>mov.l L2,r1</code> <code>mov.l @r1,r1</code> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> a95085f079b4a947daec1b23a782dd925bc94538 695 682 2020-01-30T14:58:27Z Unknown user 0 /* Use local variables */ wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <pre> mov.l L2,r1 mov.l @r1,r1 </pre> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <code>int result = var1 >> 1; //is the same as var1 / 2 but way faster</code> <code>int result = var1 >> 2; // = var1 / 4</code> <code>int result = var1 >> 3; // = var1 / 8</code> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 02add302a36e0262e00321e9782900b0bff7e20c 696 695 2020-01-30T14:59:04Z Unknown user 0 /* Integer */ wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <pre> mov.l L2,r1 mov.l @r1,r1 </pre> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <pre> int result = var1 >> 1; //is the same as var1 / 2 but way faster int result = var1 >> 2; // = var1 / 4 int result = var1 >> 3; // = var1 / 8 </pre> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <code>float result = var1 * 0.5; // same as / 2 but way faster</code> <code>float result = var1 * 0.25; // same as / 4 but way faster</code> <code>float result = var1 * 0.1; // same as / 10 but way faster</code> ==References== <references/> 387cf47bed1ade1a1c73ebc4afae1efefe422fca 697 696 2020-01-30T14:59:35Z Unknown user 0 /* Float */ wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <pre> mov.l L2,r1 mov.l @r1,r1 </pre> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. <pre> int result = var1 >> 1; //is the same as var1 / 2 but way faster int result = var1 >> 2; // = var1 / 4 int result = var1 >> 3; // = var1 / 8 </pre> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <pre> float result = var1 * 0.5; // same as / 2 but way faster float result = var1 * 0.25; // same as / 4 but way faster float result = var1 * 0.1; // same as / 10 but way faster </pre> ==References== <references/> 78150845edcb474bf361646c111487b8fc8cfef3 Indie games 0 13 683 567 2020-01-27T14:54:20Z Unknown user 0 wikitext text/x-wiki [https://dreamcast-homebrew.tumblr.com Dreamcast Homebrew] is a blog archiving image and video of indie and homebrew Dreamcast game. == In development == {| class="wikitable" style="text-align: left; width: 100%;" |- ! Name !! Description !! Release Date !! Website |- | [[Arcade Racing Legends]] || || || |- | [[Elysian Shadows]] || "Next-Gen" 2D/3D JRPG || TBD || https://www.elysianshadows.com |- | [[Hypertension: Harmony of Darkness]] |- | [[Intrepid Izzy]] || || 2020 || |- | [[Midsummer]] || || || |- | [[Non Casual Encounter]] || || || |- | [[Okinawa Rush]] || || || |- | [[Reaperi Cycle]] || || TBD || |- | [[Rizzo Island]] || 3D platformer || || |- | [[Satazius]] || || || |- | [[Shadow Gangs]] || || || |- | [[SLaVE]] || || || |- | [[Summoning Signals]] || a strange game || Late 2020 || https://www.patreon.com/12dbsoft |- | [[Swirling Blades: Desert Thunder]] || Kazade's choplifter remix ;) || || |- | [[Xenocider]] || || 2020 || |- | [[XenoCrisis]] || || 2020 || |} == Unknown Status == == Inactive == == Released == {| class="wikitable" style="text-align: left; width: 50%;" |- ! Name !! Description !! Website |- | [[4x4 Jam]] |- | [[Alice Dreams Tournament]] |- | [[Alice's Mom's Rescue]] |- | [[Another World]] |- | [[Armed Seven]] |- | [[Bang Busters]] |- | [[Battle Crust]] |- | [[Breakers]] |- | [[Captain Tomaday]] |- | [[Cool Herders]] |- | [[Dreamcastnoid]] |- | [[DUX]] |- | [[DUX 1.5]] |- | [[Elansar & Philia]] |- | [[Escape 2042 - The Truth Defenders]] |- | [[The Escapee]] |- | [[Fade to Black]] |- | [[Fast Striker ver. 1.5]] |- | [[Feet of Fury]] || Rhythm game || |- | [[Finding Teddy]] |- | [[Flashback: Quest for Identity]] |- | [[Frog Feast]] |- | [[FRUIT'Y]] |- | [[FX Unit Yuki: The Henshin Engine]] |- | [[Ganryu]] |- | [[Ghost Blade]] |- | [[Gunlord]] |- | [[Hermes]] |- | [[Inhabitants]] |- | [[Irides: Master of Blocks]] |- | [[James and Watch - Arm Breaker]] |- | [[James and Watch - Tooth Cracker]] |- | [[Last Hope]] |- | [[Last Hope: Pink Bullets]] |- | [[Leona's Tricky Adventures]] |- | [[Magic Pockets]] |- | [[Maqiupai]] |- | [[NEO XYX]] |- | [[Orion's Puzzle Collection]] |- | [[Pier Solar]] |- | [[Redux: Dark Matters]] |- | [[Redux 1.1]] |- | [[Rush Rush Rally Racing]] |- | [[Rush Rush Rally Reloaded]] |- | [[Sturmwind]] || Shooter || http://duranik.com/ |- | [[Volgarr the Viking]] || Commercial multiplatform game ported as freeware || https://volgarr.rkd.zone/ |- | [[Wind and Water Puzzle Battles]] || Puzzle game || |- | [[Zia & the Goddesses of Magic]] |} {{DCWiki:Stub}} 4f2b45723acfbda68a813f7311444e6cc4a05505 F1 fuse repair 0 95 684 500 2020-01-28T05:20:21Z Unknown user 0 Turns out R1 is actually a 1 W resistor, not 1/2 W like I had thought. F1 appears to be correct. wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K = 1°C increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C. <ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> <br> <br> R1, the other resistor on the Dreamcast controller board, is a 1 W, 13 Ω ± 5% resistor matched by Vishay-branded part number PR01000101309JR500. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. 7047fd667c92b766247d5acf10de002d323c63cd 685 684 2020-01-28T05:43:59Z Unknown user 0 Be thorough by mentioning what R1 is and what it appears that it should be replaced with (see service manual) wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K = 1°C increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C. <ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor matched by Yageo-branded part number MFR50SFTE52-13R. However, it appears that it is meant to be replaced with a 1 W, 13 Ω ± 5% resistor (matched by Vishay-branded part number PR01000101309JR500).<ref>http://www.thedreamcastjunkyard.co.uk/2017/02/the-official-sega-dreamcast-eu-service.html</ref> This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. 033c20a6ffa4c0ded84cfe2113b0a3da2a47abba 715 685 2020-02-11T02:36:08Z Unknown user 0 Note that the yageo equivalent of R1 is actually a mini sized resistor, so that anyone deciding to not go with the 1 W isn't surprised wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K (1°C) increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C.<ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> Bear in mind that a Dreamcast should never even get close to 70°C internally unless there is a major overheating or airflow restriction problem. <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor electrically matched by Yageo-branded part number MFR50SFTE52-13R (note: the Yageo part is actually a "mini" size resistor, so it is 1/2 W in the form factor normally used for 1/4 W). However, it appears that R1 is meant to be replaced with a 1 W, 13 Ω ± 5% resistor,<ref>http://www.thedreamcastjunkyard.co.uk/2017/02/the-official-sega-dreamcast-eu-service.html</ref> which is matched by Vishay-branded part number PR01000101309JR500. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. e6711e9acfddf372188ead958d8c4b2553a3e0de 716 715 2020-02-11T02:36:56Z Unknown user 0 grammar fix wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K (1°C) increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C.<ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> Bear in mind that a Dreamcast should never even get close to 70°C internally unless there is major overheating or an airflow restriction problem. <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor electrically matched by Yageo-branded part number MFR50SFTE52-13R (note: the Yageo part is actually a "mini" size resistor, so it is 1/2 W in the form factor normally used for 1/4 W). However, it appears that R1 is meant to be replaced with a 1 W, 13 Ω ± 5% resistor,<ref>http://www.thedreamcastjunkyard.co.uk/2017/02/the-official-sega-dreamcast-eu-service.html</ref> which is matched by Vishay-branded part number PR01000101309JR500. This resistor does not tend to fail as frequently as F1, however, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. 6b89500514e231b05b4f854365c412160db6cd37 717 716 2020-02-11T03:05:35Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K (1°C) increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C.<ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> Bear in mind that, under normal operating circumstances, a Dreamcast's internal ambient temperature should never even come close to 70°C (158°F)--if for some reason it does, that indicates a far more serious problem needs to be addressed (e.g. blocked airflow, failing fan, missing heat sink, being used outside in the Arabian desert, being literally on fire, etc.). <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor electrically matched by Yageo-branded part number MFR50SFTE52-13R (note: the Yageo part is actually a "mini" size resistor, so it is 1/2 W in the form factor normally used for 1/4 W). However, it appears that R1 is meant to be replaced with a 1 W, 13 Ω ± 5% resistor,<ref>http://www.thedreamcastjunkyard.co.uk/2017/02/the-official-sega-dreamcast-eu-service.html</ref> which is matched by Vishay-branded part number PR01000101309JR500. This resistor does not tend to fail as frequently as F1, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. d272efdceb9e159e165ee6d55e9ef1a712772933 718 717 2020-02-11T03:06:36Z Unknown user 0 Ok, I'm good now :P wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] <br> [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. <br> <br> The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K (1°C) increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C.<ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> Bear in mind that, under normal operating circumstances, a Dreamcast's internal ambient temperature should never even come close to 70°C (158°F)--if for some reason it does, that indicates a far more serious problem needs to be addressed (e.g. blocked airflow, failing fan, missing heat sink, being used outside in the Arabian desert, something is literally on fire, etc.). <br> <br> R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor electrically matched by Yageo-branded part number MFR50SFTE52-13R (note: the Yageo part is actually a "mini" size resistor, so it is 1/2 W in the form factor normally used for 1/4 W). However, it appears that R1 is meant to be replaced with a 1 W, 13 Ω ± 5% resistor,<ref>http://www.thedreamcastjunkyard.co.uk/2017/02/the-official-sega-dreamcast-eu-service.html</ref> which is matched by Vishay-branded part number PR01000101309JR500. This resistor does not tend to fail as frequently as F1, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. c80fe71077adec3a12489410de3adcbe07f9b0f0 723 718 2020-02-11T04:14:56Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; F1 is on the left behind the capacitor, and R1 is between the battery and bus connector.]] [[File:Dreamcast F1 fuse resistor.png|thumb|right|101px|A blown Dreamcast F1 fuse resistor]] The Dreamcast's controller board contains a fuse labelled F1 that can blow and cause the console's controller ports to no longer function. This fuse can be replaced by an automatically resetting fuse that will revert back to a functioning state within a few moments. The stock part, despite being labelled as a fuse, most closely resembles a 1/4 W, 0.39 Ω ± 10% metal film resistor. Various electronics component retailers sell part number MFR-25FTF52-0R39 by Yageo, which matches these specifications (it is actually a little bit better, and as of January 2020 it costs less than $9 USD for 100 of them). Note the green band on F1 actually represents a temperature coefficient, specifically indicating a value of 20 ppm/K--that is, for every 1K (1°C) increase in temperature, the resistance may change by no more than 20 parts per million.<ref>http://www.resistorguide.com/resistor-color-code/</ref> This information is typically provided in the datasheet of a resistor series, and the suggested Yageo part has a rating of 0ppm/°C up to 70°C (158°F), after which it becomes 100ppm/°C.<ref>https://www.mouser.com/datasheet/2/447/Yageo%20LR_MFR_2013-467719.pdf</ref> Bear in mind that, under normal operating circumstances, a Dreamcast's internal ambient temperature should never even come close to 70°C (158°F). If for some reason the console's air temperature around the controller board gets that hot, it would indicate a far more serious problem needs to be addressed (e.g. blocked airflow, failing fan, missing heat sink, being used outside in the Arabian desert, something is literally on fire, etc.). R1, the other resistor on the Dreamcast controller board, is a standard 1/2 W, 13 Ω ± 5% resistor electrically matched by Yageo-branded part number MFR50SFTE52-13R (note: the Yageo part is actually a "mini" size resistor, so it is 1/2 W in the form factor normally used for 1/4 W). However, it appears that R1 is meant to be replaced with a 1 W, 13 Ω ± 5% resistor,<ref>http://www.thedreamcastjunkyard.co.uk/2017/02/the-official-sega-dreamcast-eu-service.html</ref> which is matched by Vishay-branded part number PR01000101309JR500. This resistor does not tend to fail as frequently as F1, and generally does not need to be replaced. It is part of the timekeeping circuit with the adjacent battery. == References == 4f5e38e60eeed632c5a05db393d2f2085412ee6c Talk:GLdc 1 237 686 2020-01-28T19:34:52Z Unknown user 0 Created page with "== Note about "fast_path" == so heres the story of "fast_path". its not something i wrote, its not "new" its more just an idea that has minor code in multiple places that form..." wikitext text/x-wiki == Note about "fast_path" == so heres the story of "fast_path". its not something i wrote, its not "new" its more just an idea that has minor code in multiple places that forms together to create performant vert submission the pvr has many formats it natively "knows" and can consume and ONLY those. these are expressly laid out in DCDBSysArc990907e.pdf on page 186. in short though, most commonly used for most things 3D is polygon type 3 you get: 3d coordinates, texturing, color and some other minor control flags. very versatile and only 32 bytes per vert (so 3x4 bytes for position + 2x4 bytes for UV is 20 bytes + 1x4 Bytes for vertex colors = 24 bytes, 10 bytes "wasted") kgl, GLdc, glx, etc... generally all use this format in the end for final vertex submission to pvr (because you need to choose one, and this one is great). the idea of "fast_path" is since we are touching our 3d data anyways and then building "some" format, why not go directly to the format we need in the end? Then GLdc has code in it to determine fairly well when you are submitting something that is polygon type 3 aka pvr_vert_t aka glvert_fast_t, and instead of touching the data at all, it just immediately store queue copies it to final buffer to await submission. on other platforms, it basically just looks like an interleaved (but strided) array of data which also works fairly well. --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 13:34, 28 January 2020 (CST) fd5cc0a4d832dba822af396c22d2ed7c41c161e5 File:Dc-homebrew-sq.png 6 238 687 2020-01-28T23:31:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=logo from dreamcast homebrew webiste}} |date=2020-01-28 |source={{own}} |author=[[User:Magnes|Magnes]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 3421326bea56e860a9bd6a0fbae06af16252efb3 DCWiki:Software 4 81 689 608 2020-01-30T14:39:27Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * [[Online Services]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] |} |} 689d3b309f505273a4e1a4e45670f44d2daebc98 Online Services 0 239 690 2020-01-30T14:42:24Z Unknown user 0 Created page with "* Dreamarena Authentication * Dreamarena Registration * Games ** 2K Sports Series ** 4x4 Evolution ** Alien Front Online ** Bomberman Online ** ChuChu Rocket! ** Daytona USA 2..." wikitext text/x-wiki * Dreamarena Authentication * Dreamarena Registration * Games ** 2K Sports Series ** 4x4 Evolution ** Alien Front Online ** Bomberman Online ** ChuChu Rocket! ** Daytona USA 2001 ** F355 Challenge ** Internet Game Pack ** Ooga Booga ** Outtrigger ** Maximum Pool ** Monaco Grand Prix Online ** Next Tetris ** PBA Bowling 2001 ** POD SpeedZone ** Phantasy Star Online ** Planet Ring ** Propeller Arena ** Quake 3 Arena ** Sonic Adventure ** Speed Devils Online ** Starlancer ** Toy Racer ** Unreal Tournament ** Vanishing Point ** World Series Baseball 2K2 ** Worms World Party 5aac7476fe2205973026f1d89239523a08d0ebde 691 690 2020-01-30T14:42:44Z Unknown user 0 wikitext text/x-wiki * [[Dreamarena Authentication]] * Dreamarena Registration * Games ** 2K Sports Series ** 4x4 Evolution ** Alien Front Online ** Bomberman Online ** ChuChu Rocket! ** Daytona USA 2001 ** F355 Challenge ** Internet Game Pack ** Ooga Booga ** Outtrigger ** Maximum Pool ** Monaco Grand Prix Online ** Next Tetris ** PBA Bowling 2001 ** POD SpeedZone ** Phantasy Star Online ** Planet Ring ** Propeller Arena ** Quake 3 Arena ** Sonic Adventure ** Speed Devils Online ** Starlancer ** Toy Racer ** Unreal Tournament ** Vanishing Point ** World Series Baseball 2K2 ** Worms World Party 23f4a868a6f5acf3da41bdaf7b271b26e4d8b410 698 691 2020-01-30T15:00:24Z Unknown user 0 wikitext text/x-wiki * [[Dreamarena Authentication]] * [[Dreamarena Registration]] * Games ** 2K Sports Series ** 4x4 Evolution ** Alien Front Online ** Bomberman Online ** ChuChu Rocket! ** Daytona USA 2001 ** F355 Challenge ** Internet Game Pack ** Ooga Booga ** Outtrigger ** Maximum Pool ** Monaco Grand Prix Online ** Next Tetris ** PBA Bowling 2001 ** POD SpeedZone ** Phantasy Star Online ** Planet Ring ** Propeller Arena ** Quake 3 Arena ** Sonic Adventure ** Speed Devils Online ** Starlancer ** Toy Racer ** Unreal Tournament ** Vanishing Point ** World Series Baseball 2K2 ** Worms World Party 5b2c32324a4b28ed485f05030a56b6aeb916bc1a 701 698 2020-01-30T15:01:42Z Unknown user 0 wikitext text/x-wiki * [[Dreamarena Authentication]] * [[Dreamarena Registration]] * Games ** [[2K Sports Series]] ** 4x4 Evolution ** Alien Front Online ** Bomberman Online ** ChuChu Rocket! ** Daytona USA 2001 ** F355 Challenge ** Internet Game Pack ** Ooga Booga ** Outtrigger ** Maximum Pool ** Monaco Grand Prix Online ** Next Tetris ** PBA Bowling 2001 ** POD SpeedZone ** Phantasy Star Online ** Planet Ring ** Propeller Arena ** Quake 3 Arena ** Sonic Adventure ** Speed Devils Online ** Starlancer ** Toy Racer ** Unreal Tournament ** Vanishing Point ** World Series Baseball 2K2 ** Worms World Party 23a44a1e87d077bf33501700d59746026b150d92 703 701 2020-01-30T19:17:26Z Unknown user 0 wikitext text/x-wiki * [[Dreamarena Authentication]] * [[Dreamarena Registration]] * Games ** [[2K Sports Series]] ** [[4x4 Evolution]] ** [[Alien Front Online]] ** [[Bomberman Online]] ** [[ChuChu Rocket!]] ** [[Daytona USA 2001]] ** [[F355 Challenge]] ** [[Internet Game Pack]] ** [[Ooga Booga]] ** [[Outtrigger]] ** [[Maximum Pool]] ** [[Monaco Grand Prix Online]] ** [[Next Tetris]] ** PBA Bowling 2001 ** POD SpeedZone ** Phantasy Star Online ** Planet Ring ** Propeller Arena ** Quake 3 Arena ** Sonic Adventure ** Speed Devils Online ** Starlancer ** Toy Racer ** Unreal Tournament ** Vanishing Point ** World Series Baseball 2K2 ** Worms World Party 8d9b68dceb3caec10fbe05bdcabd04db0aa24ea1 Dreamarena Authentication 0 240 692 2020-01-30T14:43:29Z Unknown user 0 Created page with "Dreamarena was an online service used by PAL Dreamcast games. One key element of Dreamarena was its authentication system which some games (Quake 3, Toy Racer) used to get onl..." wikitext text/x-wiki Dreamarena was an online service used by PAL Dreamcast games. One key element of Dreamarena was its authentication system which some games (Quake 3, Toy Racer) used to get online when using dial-up internet. Authentication The Dreamarena authentication protocol was added fairly late on in the Dreamcast life cycle, and the library in the SDK which provided the functionality (authent.lib) only appears in the final KATANA SDK revision. A server emulator was unfortunately not available in any releases of the SDK leaked online. However, patching binaries to overcome Dreamarena is possible. Protocol In order to understand how the protocol works, it was necessary to take a look at the sh4 assembly code. Here is a brief breakdown over how the server and client communicates. This will show from connect to authentication successful. Server (First packet to client after TCP handshake): <!KADBICHBIOPETERPAN=><ONLINEGAME> <!KADBICHBIOPETERPAN=> Client (Sends back a default console id and the real console id): <!KADBICHBIOPETERPAN=><ONLINESTRT> <!KADBICHBIOPETERPAN=>0000000001 <!KADBICHBIOPETERPAN=>REAL_CONSOLE_ID <!KADBICHBIOPETERPAN=> Server: Should use the console id to lookup the user identifiers (3 digits) and the usernames associated with the console. For example: console id user id username 0000000001 111 foo 0000000001 222 bar Then if the server gets the <ONLINESTRT> 0000000001 it should return 111 foo and 222 bar. Note: Because we don't have this kind of data, which is taken from dream-key registration, just send back empty user list. <!KADBICHBIOPETERPAN=><USERLISTSP> <!KADBICHBIOPETERPAN=> Client: Will response with it's username, password and name of the game. Because we send a empty userlist, the user can choose between 0000000001 and REAL_CONSOLE_ID. The USERNAME will be the picked console id in the response packet. <!KADBICHBIOPETERPAN=><USERNAMESL> <!KADBICHBIOPETERPAN=>USERNAME <!KADBICHBIOPETERPAN=>ENTERED_PASSWORD <!KADBICHBIOPETERPAN=>NAME_OF_GAME <!KADBICHBIOPETERPAN=> Server: The below response is bascially saying You've not registered a gamer name with us before. Please select a name you would like to use whilst playing. <!KADBICHBIOPETERPAN=><GAMENAMNON> <!KADBICHBIOPETERPAN=> Otherwise use the below response to set the game name, this was taken from the console id -> gamer name mapping back in the days. If the REGISTERED_GAME_NAME is not accepted by the server, it should send suggested gamer name (not implemented). <!KADBICHBIOPETERPAN=><GAMENAMREG>REGISTERED_GAME_NAME <!KADBICHBIOPETERPAN=> Client (Response with the entered game name): <!KADBICHBIOPETERPAN=><GAMENAMESL> <!KADBICHBIOPETERPAN=>ENTERED_GAME_NAME <!KADBICHBIOPETERPAN=> Server: <!KADBICHBIOPETERPAN=><OKSERVAUTH> <!KADBICHBIOPETERPAN=> Client: <!KADBICHBIOPETERPAN=><OKAUTHORIS> <!KADBICHBIOPETERPAN=> Server (Send registration data): <!KADBICHBIOPETERPAN=><USERINFOPK> <!KADBICHBIOPETERPAN=>001<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>uk<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>uk<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>18<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo_chat_name<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo_gamer_name<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo@bar.com<!KADBICHBIOPETERPAN=> The data format of each of these parameters is: char shortname[16]; char userid[10]; char preferredlanguage[3]; char countryid[2]; char age[3]; char chatname[20]; char gamername[20]; char emailaddress[65]; Client (Sends the service type the games operates over: gmsv,lobb,chat,gmsp): <!KADBICHBIOPETERPAN=><SERVICECOD> <!KADBICHBIOPETERPAN=>SERVICE_TYPE<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=> Server (The amount of instances of the requested service type, that is if you have two lobbies then the value should be 0002): <!KADBICHBIOPETERPAN=><SERVICEDET> <!KADBICHBIOPETERPAN=>0001<!KADBICHBIOPETERPAN=> Client (Asks for the first service, will send 0001 x (amount of service instances sent above) ): <!KADBICHBIOPETERPAN=><SERVICELST> <!KADBICHBIOPETERPAN=>0001<!KADBICHBIOPETERPAN=> Server (Sends the connection data for the service type): <!KADBICHBIOPETERPAN=><SERVICESAV> <!KADBICHBIOPETERPAN=><SERVICESTR>0001 <!KADBICHBIOPETERPAN=>SERVICE_TYPE <!KADBICHBIOPETERPAN=>Service description <!KADBICHBIOPETERPAN=>IP <!KADBICHBIOPETERPAN=>PORT <!KADBICHBIOPETERPAN=><SERVICEEND><!KADBICHBIOPETERPAN=> Client (Done): <!KADBICHBIOPETERPAN=><AUTHSUCCES><!KADBICHBIOPETERPAN=> That was it, a proof-of-concept has been done with Q3 and Toyracer PAL and both works fine after the authentication. Notes: 1. The above auth. conversation is the fastest way of getting a AUTHSUCCESS, there is more in the protocol regarding fetching registration data and mapping, but for now those are not necessary to get the games to work. 2. No newline in the packages from the server. A production-ready server is being worked on. Games Known to use Authentication Toy Racer Quake 3 (PAL) b2ca6b4391304eb30ebc654c0ead6695c1bfc8cb 693 692 2020-01-30T14:51:16Z Unknown user 0 wikitext text/x-wiki Dreamarena was an online service used by PAL Dreamcast games. One key element of Dreamarena was its authentication system which some games (Quake 3, Toy Racer) used to get online when using dial-up internet. '''Authentication''' The Dreamarena authentication protocol was added fairly late on in the Dreamcast life cycle, and the library in the SDK which provided the functionality (authent.lib) only appears in the final KATANA SDK revision. A server emulator was unfortunately not available in any releases of the SDK leaked online. However, patching binaries to overcome Dreamarena is possible. '''Protocol''' In order to understand how the protocol works, it was necessary to take a look at the sh4 assembly code. Here is a brief breakdown over how the server and client communicates. This will show from connect to authentication successful. '''Server (First packet to client after TCP handshake):''' <code><pre><!KADBICHBIOPETERPAN=><ONLINEGAME> <!KADBICHBIOPETERPAN=></pre></code> '''Client (Sends back a default console id and the real console id):''' <!KADBICHBIOPETERPAN=><ONLINESTRT> <!KADBICHBIOPETERPAN=>0000000001 <!KADBICHBIOPETERPAN=>REAL_CONSOLE_ID <!KADBICHBIOPETERPAN=> '''Server:''' Should use the console id to lookup the user identifiers (3 digits) and the usernames associated with the console. For example: console id user id username 0000000001 111 foo 0000000001 222 bar Then if the server gets the <ONLINESTRT> 0000000001 it should return 111 foo and 222 bar. Note: Because we don't have this kind of data, which is taken from dream-key registration, just send back empty user list. <!KADBICHBIOPETERPAN=><USERLISTSP> <!KADBICHBIOPETERPAN=> '''Client:''' Will response with it's username, password and name of the game. Because we send a empty userlist, the user can choose between 0000000001 and REAL_CONSOLE_ID. The USERNAME will be the picked console id in the response packet. <!KADBICHBIOPETERPAN=><USERNAMESL> <!KADBICHBIOPETERPAN=>USERNAME <!KADBICHBIOPETERPAN=>ENTERED_PASSWORD <!KADBICHBIOPETERPAN=>NAME_OF_GAME <!KADBICHBIOPETERPAN=> '''Server:''' The below response is bascially saying You've not registered a gamer name with us before. Please select a name you would like to use whilst playing. <!KADBICHBIOPETERPAN=><GAMENAMNON> <!KADBICHBIOPETERPAN=> Otherwise use the below response to set the game name, this was taken from the console id -> gamer name mapping back in the days. If the REGISTERED_GAME_NAME is not accepted by the server, it should send suggested gamer name (not implemented). <!KADBICHBIOPETERPAN=><GAMENAMREG>REGISTERED_GAME_NAME <!KADBICHBIOPETERPAN=> Client (Response with the entered game name): <!KADBICHBIOPETERPAN=><GAMENAMESL> <!KADBICHBIOPETERPAN=>ENTERED_GAME_NAME <!KADBICHBIOPETERPAN=> '''Server:''' <!KADBICHBIOPETERPAN=><OKSERVAUTH> <!KADBICHBIOPETERPAN=> '''Client:''' <!KADBICHBIOPETERPAN=><OKAUTHORIS> <!KADBICHBIOPETERPAN=> Server (Send registration data): <!KADBICHBIOPETERPAN=><USERINFOPK> <!KADBICHBIOPETERPAN=>001<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>uk<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>uk<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>18<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo_chat_name<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo_gamer_name<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo@bar.com<!KADBICHBIOPETERPAN=> The data format of each of these parameters is: char shortname[16]; char userid[10]; char preferredlanguage[3]; char countryid[2]; char age[3]; char chatname[20]; char gamername[20]; char emailaddress[65]; '''Client (Sends the service type the games operates over: gmsv,lobb,chat,gmsp):''' <!KADBICHBIOPETERPAN=><SERVICECOD> <!KADBICHBIOPETERPAN=>SERVICE_TYPE<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=> '''Server (The amount of instances of the requested service type, that is if you have two lobbies then the value should be 0002):''' <!KADBICHBIOPETERPAN=><SERVICEDET> <!KADBICHBIOPETERPAN=>0001<!KADBICHBIOPETERPAN=> '''Client (Asks for the first service, will send 0001 x (amount of service instances sent above) ):''' <!KADBICHBIOPETERPAN=><SERVICELST> <!KADBICHBIOPETERPAN=>0001<!KADBICHBIOPETERPAN=> '''Server (Sends the connection data for the service type):''' <!KADBICHBIOPETERPAN=><SERVICESAV> <!KADBICHBIOPETERPAN=><SERVICESTR>0001 <!KADBICHBIOPETERPAN=>SERVICE_TYPE <!KADBICHBIOPETERPAN=>Service description <!KADBICHBIOPETERPAN=>IP <!KADBICHBIOPETERPAN=>PORT <!KADBICHBIOPETERPAN=><SERVICEEND><!KADBICHBIOPETERPAN=> '''Client (Done):''' <!KADBICHBIOPETERPAN=><AUTHSUCCES><!KADBICHBIOPETERPAN=> That was it, a proof-of-concept has been done with Q3 and Toyracer PAL and both works fine after the authentication. Notes: 1. The above auth. conversation is the fastest way of getting a AUTHSUCCESS, there is more in the protocol regarding fetching registration data and mapping, but for now those are not necessary to get the games to work. 2. No newline in the packages from the server. A production-ready server is being worked on. '''Games Known to use Authentication''' * Toy Racer * Quake 3 (PAL) 537c9a2a3571a5c32c32199ec134d02ed647a3be 694 693 2020-01-30T14:56:51Z Unknown user 0 wikitext text/x-wiki Dreamarena was an online service used by PAL Dreamcast games. One key element of Dreamarena was its authentication system which some games (Quake 3, Toy Racer) used to get online when using dial-up internet. '''Authentication''' The Dreamarena authentication protocol was added fairly late on in the Dreamcast life cycle, and the library in the SDK which provided the functionality (authent.lib) only appears in the final KATANA SDK revision. A server emulator was unfortunately not available in any releases of the SDK leaked online. However, patching binaries to overcome Dreamarena is possible. '''Protocol''' In order to understand how the protocol works, it was necessary to take a look at the sh4 assembly code. Here is a brief breakdown over how the server and client communicates. This will show from connect to authentication successful. '''Server (First packet to client after TCP handshake):''' <pre> <!KADBICHBIOPETERPAN=><ONLINEGAME> <!KADBICHBIOPETERPAN=> </pre> '''Client (Sends back a default console id and the real console id):''' <pre> <!KADBICHBIOPETERPAN=><ONLINESTRT> <!KADBICHBIOPETERPAN=>0000000001 <!KADBICHBIOPETERPAN=>REAL_CONSOLE_ID <!KADBICHBIOPETERPAN=> </pre> '''Server:''' Should use the console id to lookup the user identifiers (3 digits) and the usernames associated with the console. For example: console id user id username 0000000001 111 foo 0000000001 222 bar Then if the server gets the <ONLINESTRT> 0000000001 it should return 111 foo and 222 bar. Note: Because we don't have this kind of data, which is taken from dream-key registration, just send back empty user list. <pre> <!KADBICHBIOPETERPAN=><USERLISTSP> <!KADBICHBIOPETERPAN=> </pre> '''Client:''' Will response with it's username, password and name of the game. Because we send a empty userlist, the user can choose between 0000000001 and REAL_CONSOLE_ID. The USERNAME will be the picked console id in the response packet. <pre> <!KADBICHBIOPETERPAN=><USERNAMESL> <!KADBICHBIOPETERPAN=>USERNAME <!KADBICHBIOPETERPAN=>ENTERED_PASSWORD <!KADBICHBIOPETERPAN=>NAME_OF_GAME <!KADBICHBIOPETERPAN=> </pre> '''Server:''' The below response is bascially saying You've not registered a gamer name with us before. Please select a name you would like to use whilst playing. <pre> <!KADBICHBIOPETERPAN=><GAMENAMNON> <!KADBICHBIOPETERPAN=> </pre> Otherwise use the below response to set the game name, this was taken from the console id -> gamer name mapping back in the days. If the REGISTERED_GAME_NAME is not accepted by the server, it should send suggested gamer name (not implemented). <pre> <!KADBICHBIOPETERPAN=><GAMENAMREG>REGISTERED_GAME_NAME <!KADBICHBIOPETERPAN=> </pre> '''Client (Response with the entered game name):''' <pre> <!KADBICHBIOPETERPAN=><GAMENAMESL> <!KADBICHBIOPETERPAN=>ENTERED_GAME_NAME <!KADBICHBIOPETERPAN=> </pre> '''Server:''' <pre> <!KADBICHBIOPETERPAN=><OKSERVAUTH> <!KADBICHBIOPETERPAN=> </pre> '''Client:''' <pre> <!KADBICHBIOPETERPAN=><OKAUTHORIS> <!KADBICHBIOPETERPAN=> </pre> '''Server (Send registration data):''' <pre> <!KADBICHBIOPETERPAN=><USERINFOPK> <!KADBICHBIOPETERPAN=>001<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>uk<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>uk<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>18<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo_chat_name<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo_gamer_name<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=>foo@bar.com<!KADBICHBIOPETERPAN=> </pre> The data format of each of these parameters is: char shortname[16]; char userid[10]; char preferredlanguage[3]; char countryid[2]; char age[3]; char chatname[20]; char gamername[20]; char emailaddress[65]; '''Client (Sends the service type the games operates over: gmsv,lobb,chat,gmsp):''' <pre> <!KADBICHBIOPETERPAN=><SERVICECOD> <!KADBICHBIOPETERPAN=>SERVICE_TYPE<!KADBICHBIOPETERPAN=> <!KADBICHBIOPETERPAN=> </pre> '''Server (The amount of instances of the requested service type, that is if you have two lobbies then the value should be 0002):''' <pre> <!KADBICHBIOPETERPAN=><SERVICEDET> <!KADBICHBIOPETERPAN=>0001<!KADBICHBIOPETERPAN=> </pre> '''Client (Asks for the first service, will send 0001 x (amount of service instances sent above) ):''' <pre> <!KADBICHBIOPETERPAN=><SERVICELST> <!KADBICHBIOPETERPAN=>0001<!KADBICHBIOPETERPAN=> </pre> '''Server (Sends the connection data for the service type):''' <pre> <!KADBICHBIOPETERPAN=><SERVICESAV> <!KADBICHBIOPETERPAN=><SERVICESTR>0001 <!KADBICHBIOPETERPAN=>SERVICE_TYPE <!KADBICHBIOPETERPAN=>Service description <!KADBICHBIOPETERPAN=>IP <!KADBICHBIOPETERPAN=>PORT <!KADBICHBIOPETERPAN=><SERVICEEND><!KADBICHBIOPETERPAN=> </pre> '''Client (Done):''' <pre> <!KADBICHBIOPETERPAN=><AUTHSUCCES><!KADBICHBIOPETERPAN=> </pre> That was it, a proof-of-concept has been done with Q3 and Toyracer PAL and both works fine after the authentication. Notes: 1. The above auth. conversation is the fastest way of getting a AUTHSUCCESS, there is more in the protocol regarding fetching registration data and mapping, but for now those are not necessary to get the games to work. 2. No newline in the packages from the server. A production-ready server is being worked on. '''Games Known to use Authentication''' * Toy Racer * Quake 3 (PAL) 60aabd92cd5102a5c4777b7863e291212724d5ad Dreamarena Registration 0 241 699 2020-01-30T15:01:04Z Unknown user 0 Created page with "The Dreamarena Registration service is what is used when you insert DreamKey 1.0 or 1.5 into a new (unregistered) Dreamcast. It takes care of creating a Dreamarena account. '..." wikitext text/x-wiki The Dreamarena Registration service is what is used when you insert DreamKey 1.0 or 1.5 into a new (unregistered) Dreamcast. It takes care of creating a Dreamarena account. '''Domains and Ports''' registration.dream-key.com (80?) 42ea936d353f9fec303a990eeba0265ed7ceb36f 700 699 2020-01-30T15:01:12Z Unknown user 0 wikitext text/x-wiki The Dreamarena Registration service is what is used when you insert DreamKey 1.0 or 1.5 into a new (unregistered) Dreamcast. It takes care of creating a Dreamarena account. '''Domains and Ports''' registration.dream-key.com (80?) 86f5d62d07f3029c5503ae6cc0ea1ecf27485c23 2K Sports Series 0 242 702 2020-01-30T15:06:26Z Unknown user 0 Created page with "==Protocol== <big>'''Domains and Ports'''</big> '''NBA 2K2''' * authorize.vc-nba2k2.games.sega.net * region.vc-nba2k2.games.sega.net * record.vc-nba2k2.games.sega.net ''..." wikitext text/x-wiki ==Protocol== <big>'''Domains and Ports'''</big> '''NBA 2K2''' * authorize.vc-nba2k2.games.sega.net * region.vc-nba2k2.games.sega.net * record.vc-nba2k2.games.sega.net '''NCAA 2K2''' * authorize.vc-ncaa2k2.games.sega.net * region.vc-ncaa2k2.games.sega.net * record.vc-ncaa2k2.games.sega.net '''NFL 2K2''' * authorize.vc-nfl2k2.games.sega.net * region.vc-nfl2k2.games.sega.net * record.vc-nfl2k2.games.sega.net '''NFL 2K1''' * authorize.vc-nfl2k1.games.sega.com/ * region.vc-nfl2k1.games.sega.com '''NBA 2K1''' * authorize.vc-nba2k1.games.sega.net * region.vc-nba2k1.games.sega.net 6e26a39cdecfb8589035d002373007c5a6382fdf 4x4 Evolution 0 243 704 2020-01-30T19:18:40Z Unknown user 0 Created page with "== Protocol== '''Domains and Ports''' * master.4x4evolution.com * master2.4x4evolution.com * master3.4x4evolution.com * master4.4x4evolution.com * master5.4x4evolution.com *..." wikitext text/x-wiki == Protocol== '''Domains and Ports''' * master.4x4evolution.com * master2.4x4evolution.com * master3.4x4evolution.com * master4.4x4evolution.com * master5.4x4evolution.com * master6.4x4evolution.com * master7.4x4evolution.com * master8.4x4evolution.com * master9.4x4evolution.com == Wireshark Packet Logs == [http://www.dreamcastlive.net/dreamcast-packet-logs.html Dreamcast Live] 7307d35ea7c1771f41ee97c0b83251450140f1bd Alien Front Online 0 244 705 2020-01-30T19:20:05Z Unknown user 0 Created page with "== Protocol== '''Domains and Ports''' * master.bomberman-hudson.games.sega.net" wikitext text/x-wiki == Protocol== '''Domains and Ports''' * master.bomberman-hudson.games.sega.net f3cc1df1a02ff2e1a5cf7272f23ae79e2c9a9aee 707 705 2020-01-30T19:31:13Z Unknown user 0 /* Protocol */ wikitext text/x-wiki == Status == '''Completely revived - Open Beta Testing is LIVE -''' Big shoutout to '''Shuouma''' for helping me with testing, debugging and correcting some bugs affecting the Linux platform (which was originally not going to be the target OS for the servers), which both resulted in memory and CPU-usage issues as well as deploying the servers at his own VPS. Also a big thanks to both '''Pcwzrd13''' for being extremely helpful with testing and everyone who have donated to the DCSERV project which was fundamental at keeping motivation as well as progress ongoing. == Protocol == AFO originally uses Kage, or Kage Lite rather ("Kagel") - The SEGA network system developed in-house solely for the Dreamcast (99%, read below about evolution) by a bigger group of developers servers/framework for its online mode. '''MORE''' (mostly 1st & 2nd-party) titles uses the same, few at the very least, almost identical system - which was constantly under development and ended up as the infamous '''SNAP''' for the other 6th generation of consoles in the end, implementing quite a few changes from what started as KAGE on the Dreamcast. '''SNAP''' is the system that was sold to NOKIA. A new, although heavily delayed, surprise set of newly written replacement system shipping with AFO-servers as an apologize for the very long wait since promised (100% compatible, yes - but in debug-mode for long-term logging. Yes, voice messages too.) developed by DCSERV is complete but probably not bug-free. A different networking system/concept with proxies, offloading and KCIS request servers (with more functionality than both SNAP and KAGE) were originally going to be commercialized by DCSERV's founder, but as of progress so far the AFO servers does not work without some parts originally being exclusive to that of the commercial system, so it was decided to split up the servers for AFO from the rest of the system/project and put the remaining on hold. An ongoing unified replacement Kage and SNAP network system is currently in the works, and is what started everything related to 1st and 2nd party titles like AFO's resurrection. AFO is special in that the main hostname for its online-mode is an IP-address (plain-text, IPv4 syntax) hardcoded (as in: No option to enter a alternative hostname/IP) at memory offset 0xFB118 in 1st_read.bin. This is most likely the reason that the game was suddenly offline (as with Daytona USA 2001) when SEGA sold a network block to AT&T. Confirmed. Patching the hardcoded IP-address in-memory will be covered with a patcher disc (by BlueCrab, similar to the one used for Planet Ring and PSO) which will be released asap once the servers are deployed. Since the servers were originally going to be released a very long time ago, there will be an OPEN testing-phase for some time before release with an open-source license, to cover up for the delay. As a bonus, I heard some PRETTY, PROBABLY GOING TO HAPPEN WITH THE RELEASE-type of rumours about a leaked, alternative version with more hardware and software support as well as an already set IP that matches the one used by the community. Some rumours are bad though, where the Teltone+Netopia-users will still be affected by the same "bug" where the game returns back to the main menu if the dial-up number is "invalid" (see below). The affected users could, given that the rumours are true, as with anyone else, connect trough the new hardware support. == Process == The game first does a POST at port 8080 to a "bootstrap"-server, which invokes an instance of a "status server" which in turn launches the actual game servers with proper arguments which (probably) in this case is a key part of the whole Kage/SNAP networking system. Other (unknown at the time being) games is known to operate in the exact same mode, confirming the theory that more than 1 game used this system. The game also has support for an online ranking system - which of course also is completely revived. As the game is built upon a newer (v1.2) version of the "NextGenIP" (or "NextGen" as often called) network stack (by NexGen Software), the first of its kind, and built with the SDK version 11b through Cygwin on Windows 2000 - a fork of the NAOMI Arcade-version "Army vs Aliens" or "AVA" in which the online-modes of both games were supposed to be cross-online multiplayer and was at some point of the development (Confirmed.), the first of its kind supposed to be cross-online multiplayer compatible with a NAOMI title. The NextGenIP has minor differences between the revisions included in later SDKs, and most information about it is that a dedicated SDK was supposed to be made - unsure if the SDK was replaced by documentation available to developers online. The stack is a set of libraries which supported the Dreamcast hardware and simply allowed developers to implement an already existing network system (probably for a fee), with or without included KAGE-generic game servers, tied up with rest of the SEGA.com. Some Japanese titles were shipped with the same networking stack, while most sticking to the KDDI system (not using the same client stack), which MAY indicate that the later releases of KAGE and SNAP was (PROBABLY) not so different from KDDI, and if the case might prove to be useful with regards to revive Japanese-exclusives that may be compatible with the same system used for 1st and 2nd party titles for the Dreamcast in the rest of the world. A proto SN@P server has been reverse engineered and tested with the key features such as rUDP+UDP+TCP packets for transmission of data, with encryption and is merely a proof-of-concept for PS2 titles such as RE:Outbreak by DCSERV. There is documentable doubt that the Dreamcast never used a system called SNAP (even if saying so, something I have never seen - because the similarities between the two is almost only in their proof-of-concept that all developers, probably for a fee, could use a finished and generic (or rather evolving, really) online system for their games developed in-house. Because of how small these similarities are, making a new system compatible with multiple games takes a lot of effort - but will hopefully be worth it in the end. == Servers and clients == A total of 14 or 16 arguments can be manually given to the new replacement system (which BY THE WAY (hint hint) has no name yet), which indicates that other games used KAGE aswell. The game was supposed to be cross-multiplayer compatible with the NAOMI-version (Army vs Aliens) of the game through either: * Optical Link * Serial-modem * Internal modem * Broadband adapter (although the commercial release lacks support for it, but is included in the stack used for the game) The Dreamcast game was ported and developed using the Katana SDK11b on Windows NT. Servers meant to be used for the NAOMI-title were built using gcc-2.95-3 and the target platform was Solaris, SunOS and IRIX written in pre-ANSI C. '''Domains and Ports''' * 63.251.242.131 (Rumour has it that this was Takashi Kosakas workstation - a SEGA networking engineer) in plain-text at memory offset 0xFB118 in IPv4-syntax. * auriga.segasoft.com (Investigation of the purpose of this is ongoing) '''How To''' Since the games' target host is set to connect to an IP instead of a host name, a redirection in form of in-memory modifications at the offset above must be done to be able to play. Simply masking the IP through a custom DNS server will not work, and the modifications done to the target host *MUST* be in IPv4 format for the offset to be handled correctly. '''Alternatives/methods for this include:''' * Using iptables with a DC-Linux-setup (see rule below for Linux users). * Kazade's newly created DreamPi 1.5 image for all Raspberry Pi models with a supported USB-modem, with line voltage inducer (required regardless of Dreamcast modem revision due to the USB modem requiring line voltage as well). Phone line simulators will also provide line voltage. * Using a Katana Devkit with a modem, modifying the IP at runtime. * Using the soon to be released AFO Patcher disc, originally created by BlueCrab, based on his previous versions of the PSO Patcher disc and Planet Ring patcher disc which will allow all other dial-up methods to be used as normal, with the exception of: * Netopia users with '''Teltone TLS or similar phone-line simulators''' that require a specific single or double digit number to be dialed (ie. "1" or "2"), resulting in a "invalid" number because of the minimum length of =<7 digits '''will''' have issues connecting due to the fact that the game will exit back to the main menu because of trying to reset the modem, clear memory and read the ISP information again.** '''IPtables rule:''' # iptables -t nat -A PREROUTING -p tcp -d 63.251.242.131 -j DNAT —to-destination 146.185.135.179 668146598eda552688fc8c2da909f0f4c973c7c0 Bomberman Online 0 245 706 2020-01-30T19:20:31Z Unknown user 0 Created page with "== Protocol== '''Domains and Ports''' * master.bomberman-hudson.games.sega.net" wikitext text/x-wiki == Protocol== '''Domains and Ports''' * master.bomberman-hudson.games.sega.net f3cc1df1a02ff2e1a5cf7272f23ae79e2c9a9aee File:Sega logo.png 6 246 708 2020-02-02T08:57:51Z Unknown user 0 The official Sega logo. wikitext text/x-wiki == Summary == The official Sega logo. 9048ef0623e3e82b07b3fce7d1ab56ad7014f48c Sega 0 247 709 2020-02-02T08:59:41Z Unknown user 0 Created page with "[[File:Sega_logo.png|thumb|right|Official Sega logo]] '''Sega''' (セガ) is the company that released the Dreamcast. It is currently a subsidiary of Sega Sammy Holdings. I..." wikitext text/x-wiki [[File:Sega_logo.png|thumb|right|Official Sega logo]] '''Sega''' (セガ) is the company that released the Dreamcast. It is currently a subsidiary of Sega Sammy Holdings. It was founded on June 3, 1960, when Japan Entertainment Products was created and used the trade name Sega, a contraction of its preceding company, '''Service Games'''. However, it has roots in companies dating back to the 1930s. ==Formation of Sega== In 1930, Irving Bromberg founded a coin-operated machine distribution company named '''Irving Bromberg Co.'''. The company distributed coin-operated machines to New York City, Boston, and Washington, D.C. In 1933, he sold the New York office to office manager Leon Taksen. Then, according to an advertisement in the July 1933 issue of the Coin Machine Journal, the Supreme Vending Company of Brooklyn had purchased the Irving Bromberg Company of Brooklyn. After the sale of his company, Bromberg moved to Los Angeles, California. In 1934, he started a new coin-operated machine distribution company in Los Angeles named '''Standard Games'''. By 1940, Irving Bromberg's son, Martin Bromley, had enlisted in the Navy and was sent to Honolulu, Hawaii. However, he was placed on inactive duty due to his employment at the Pearl Harbor Shipyard. Later that year, Martin Bromley, his father Irving Bromberg, and a fellow shipyard worker named James Humpert formed a company in Honolulu, Hawaii named Standard Games. This company provided coin-operated amusement machines to military bases, for soldiers to use during their leisure time. In 1945, after World War II had ended, Standard Games was sold. The three Americans that founded that company started a new coin-operated machine distributor named Service Games, due to the company's focus on military personnel. In 1951, the United States government passed a law that outlawed slot machines in United States territories. Thus, in 1952, Martin Bromley sent two of his employees, Richard Stewart and Ray LeMaire, to Tokyo, Japan. They set up a distribution company there to provide coin-operated slot machines to the United States military bases in Japan. By 1953, this company was active and operating as Service Games of Japan. In 1954, an officer in the United States Air Force stationed in Japan, David Rosen, set up a two-minute photo business. This company, '''Rosen Enterprises''', began importing coin-operated games to Japan in 1957. On May 31, 1960, Service Games closed Service Games Japan, and on June 3rd, two new companies were set up to handle the business. '''Japan Entertainment Products (日本娯楽物産, Nihon Goraku Bussan)''' was set up to handle distribution, while '''Japan Machinery Manufacturing (日本機械製造, Nihon Kikai Seizō)''' was set up to handle manufacturing. In 1960, Japan Entertainment Products released the Sega 1000 jukebox, named after the first two letters in the first and second word of Service Games. The game was a hit, and as a result, the company, while still retaining its legal name, began using the trade name of Sega. In 1964, Japan Entertainment Products acquired Japan Machinery Manufacturing, bringing both arms of the business together once more. By 1965, Rosen Enterprises had grown to a point where they operated over 200 arcades in Japan. That year, David Rosen sought a merger of Rosen Enterprises and Japan Entertainment Products. In the resulting company, David Rosen was named the chief executing officer. The company named '''Sega Enterprises''', after the trade name of Japan Entertainment Products. 0aea7ce71b915e49a28269e289b86526ae67a89e Karaoke 0 92 710 278 2020-02-04T01:07:32Z Unknown user 0 wikitext text/x-wiki The Karaoke deck is an expansion for the Dreamcast that allows the console to be used as a karaoke machine. It connects to the [[G2 bus]] and sits below the console, doubling its size vertically. It has two microphone jacks for karaoke microphones as well as volume dials. [https://dcemulation.org/phpBB/viewtopic.php?t=102379 images available] {{DCWiki:Stub}} 3d3837c2d08f4e3fed0a21a914d53533ee467bce DreamEye webcam 0 248 711 2020-02-04T01:09:01Z Unknown user 0 Created page with "DreamEye is a webcam for Dreamcast used in conjunction with [[Visual Park]]. [https://dcemulation.org/phpBB/viewtopic.php?f=36&t=102381&p=1035848 images available]" wikitext text/x-wiki DreamEye is a webcam for Dreamcast used in conjunction with [[Visual Park]]. [https://dcemulation.org/phpBB/viewtopic.php?f=36&t=102381&p=1035848 images available] 984560d118e088faf91e7ed9a6910937e4de202f IDE hard drive modification 0 25 712 290 2020-02-06T16:48:10Z Unknown user 0 wikitext text/x-wiki The Dreamcast IDE hard drive modification allows one to connect an IDE hard drive (or SATA hard drive, with a proper compatible adapter) to the Dreamcast for storage of files and games. Using [[DreamShell]], one can execute games from the hard drive with great (although not perfect) compatibility and access times. [https://github.com/Cpasjuste/retrodream RetroDream] is a frontend that can be used in conjunction with this modification to manage files and launch games. {{DCWiki:Stub}} 06431d4ec000323432ff72f13499c8a6597aa4d5 IP.BIN 0 35 713 328 2020-02-08T03:16:06Z Unknown user 0 /* General Header Information */ wikitext text/x-wiki The Dreamcast bootsector (commonly named '''IP.BIN''') is placed on a [[GD-ROM]] or a [[MIL-CD]] in the first 16 sectors of the data track from which the Dreamcast is booting. It contains information about the software on the disc, including [[region protection]], as well as the code that displays the Sega copyright screen and prepares the system for the launch of a game title. Originally the bootsector was lifted from Dreamcast games to boot homebrew software, but technically using this copyrighted code was illegal in some jurisdictions. Homebrew coder [[LiENUS]] originally [[LiENUS's IP.BIN|rewrote the IP.BIN file]], replacing as much as possible with free code. The only code that remains in this homebrew IP.BIN is Sega's copyright screen code, which is required to be unmodified in order for the disc to boot (the system checks it against a copy of the code held within the BIOS ROM). It is believed by some that using this last bit of code is legal due to the legal precedent set by ''[http://digital-law-online.info/cases/24PQ2D1561.htm Sega v. Accolade]''. New, additional functionality has been added to the IP.BIN in the [[neoIP]] replacement IP.BIN project. It is currently able to load homebrew and official Katana or Windows CE binaries from either [[GD-ROM]] or [[CD-ROM]]. == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an [[MR Image]] * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} {| class="wikitable" !Offset !Contents |- |000-00F |Hardware ID (always "SEGA SEGAKATANA ") |- |010-01F |Maker ID (always "SEGA ENTERPRISES") |- |020-02F |Device Information (see below) |- |030-037 |Area Symbols (see below) |- |038-03F |Peripherals (see below) |- |040-049 |Product number ("HDR-nnnn" etc.) |- |04A-04F |Product version |- |050-05F |Release date (YYYYMMDD) |- |060-06F |Boot filename (usually "1ST_READ.BIN") |- |070-07F |Name of the company that produced the disc |- |080-0FF |Name of the software |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * A custom [[MR Image]] can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== This is Generally where all the base setup code is kept so our binary has a known, and clean execution environment in which it starts. In [[Warez]] releases this is the area that is responsible for a very sneaky trick. The [[1ST_READ.BIN]] binary is kept as is on the disc, but then when scramble loaded by the bios (See [[Dreamcast_Boot_Process]] for further)) it will be unusable, so code was written to unscramble, the now ruined binary, in-place. The second part of this trick also reinitializes the [[GD-ROM]] drive and passes the [[HOLLY]] bios check so that the game may access the data on the disc and execute normally. ==References== <references/> 58d9df3811bda87302e58034b09d8a86fcb7dafb 714 713 2020-02-08T03:16:39Z Unknown user 0 /* General Header Information */ wikitext text/x-wiki The Dreamcast bootsector (commonly named '''IP.BIN''') is placed on a [[GD-ROM]] or a [[MIL-CD]] in the first 16 sectors of the data track from which the Dreamcast is booting. It contains information about the software on the disc, including [[region protection]], as well as the code that displays the Sega copyright screen and prepares the system for the launch of a game title. Originally the bootsector was lifted from Dreamcast games to boot homebrew software, but technically using this copyrighted code was illegal in some jurisdictions. Homebrew coder [[LiENUS]] originally [[LiENUS's IP.BIN|rewrote the IP.BIN file]], replacing as much as possible with free code. The only code that remains in this homebrew IP.BIN is Sega's copyright screen code, which is required to be unmodified in order for the disc to boot (the system checks it against a copy of the code held within the BIOS ROM). It is believed by some that using this last bit of code is legal due to the legal precedent set by ''[http://digital-law-online.info/cases/24PQ2D1561.htm Sega v. Accolade]''. New, additional functionality has been added to the IP.BIN in the [[neoIP]] replacement IP.BIN project. It is currently able to load homebrew and official Katana or Windows CE binaries from either [[GD-ROM]] or [[CD-ROM]]. == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an [[MR Image]] * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} === Meta information === {| class="wikitable" !Offset !Contents |- |000-00F |Hardware ID (always "SEGA SEGAKATANA ") |- |010-01F |Maker ID (always "SEGA ENTERPRISES") |- |020-02F |Device Information (see below) |- |030-037 |Area Symbols (see below) |- |038-03F |Peripherals (see below) |- |040-049 |Product number ("HDR-nnnn" etc.) |- |04A-04F |Product version |- |050-05F |Release date (YYYYMMDD) |- |060-06F |Boot filename (usually "1ST_READ.BIN") |- |070-07F |Name of the company that produced the disc |- |080-0FF |Name of the software |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * A custom [[MR Image]] can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== This is Generally where all the base setup code is kept so our binary has a known, and clean execution environment in which it starts. In [[Warez]] releases this is the area that is responsible for a very sneaky trick. The [[1ST_READ.BIN]] binary is kept as is on the disc, but then when scramble loaded by the bios (See [[Dreamcast_Boot_Process]] for further)) it will be unusable, so code was written to unscramble, the now ruined binary, in-place. The second part of this trick also reinitializes the [[GD-ROM]] drive and passes the [[HOLLY]] bios check so that the game may access the data on the disc and execute normally. ==References== <references/> d61d7f3ef9072b7e6ebfed0c8fca7dca473e8d7f File:58747972.png 6 249 719 2020-02-11T03:26:22Z Unknown user 0 wikitext text/x-wiki Broadband Adapters were made in black and white colors. The black ones were only available via mail order from Sega Direct in Japan, whereas the white ones saw release in Japan and North America. 2c8243656048f9d868c4b560f490df0f633cec93 Broadband adapter 0 5 720 634 2020-02-11T03:48:47Z Unknown user 0 Lots of updates, added a pic of mine (Is this the only wiki online with a real picture of a black BBA? :O ) wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via mail order from Sega Direct in Japan. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .cdi and .elf files over the BBA. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) {{DCWiki:Stub}} 3124e9ecb5c0521548022399e3ee8851e04d4ef1 722 720 2020-02-11T04:11:56Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via mail order from Sega Direct in Japan. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .cdi and .elf files over the BBA. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) {{DCWiki:Stub}} == References == a82af4b1992db75cdc081513ab86895918dbbca2 725 722 2020-02-11T05:03:39Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from Sega Direct in Japan. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .cdi and .elf files over the BBA. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) {{DCWiki:Stub}} == References == 48e027d8cc752249c920d8fc247f933f0e60e267 Battery replacement 0 96 721 287 2020-02-11T04:11:35Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2450.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of the ML2032 in the future. It is recommended '''not''' to use the LIR2032 battery type as the Dreamcast does not output the voltage necessary for it to properly and fully recharge. Specifically, the ML2032 (and ML2020 and ML2450) are 3V batteries,<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref><ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref><ref>Datasheets for the ML2450 seem to have fallen off the face of the Earth, but the one that came in my Japanese R7 Dreamcast was 3V.</ref> while the LIR2032 type is generally 3.6V or 3.7V.<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> == Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 28385f601664dd29e9a32496ff77955a77a1d789 LAN adapter 0 31 724 522 2020-02-11T04:19:14Z Unknown user 0 wikitext text/x-wiki The Dreamcast '''LAN Adapter (HIT-300)''' is a Japanese-only peripheral that connects to the [[G2 bus]] in place of the modem and provides the Dreamcast with 10mbps network connectivity. It uses a Fujitsu MB86967 chip, and should not be confused with the more common and vastly superior [[Broadband adapter | Dreamcast Broadband Adapter]], which uses a RealTek 8139C chip. The only official software that works with the LAN adapter is the "Dream Passport 2 for LAN" web browser. No official games from any region are compatible with the LAN adapter. Homebrew software that is compatible with the broadband adapter is usually also compatible with the LAN adapter, however, software is not often tested with the LAN adapter explicitly due to its rarity. {{DCWiki:Stub}} a5fd91b10f4c58731c467b8c70c399ef6859df33 BIOS modification 0 12 726 282 2020-02-11T15:00:29Z Unknown user 0 wikitext text/x-wiki The Dreamcast's BIOS chip can be replaced (or a secondary chip added) to remove region checks, A/V connectivity compatibility checks, and add new features. Examples of custom BIOS versions include japanese-cake's BIOS hacks [https://japanese-cake.livejournal.com/8489.html v1.031] and [https://japanese-cake.livejournal.com/10056.html v1.032] and cpasjuste's [https://github.com/Cpasjuste/dreamboot DreamBoot]. {{DCWiki:Stub}} 3887d12296a329d9ef0f3ece58d62887e8375e2c BIOS modification 0 12 727 726 2020-02-11T15:00:41Z Unknown user 0 wikitext text/x-wiki The Dreamcast's BIOS chip can be replaced (or a secondary chip added) to remove region checks, A/V connectivity compatibility checks, and add new features. Examples of custom BIOS versions include japanese-cake's BIOS hacks [https://japanese-cake.livejournal.com/8489.html v1.031] and [https://japanese-cake.livejournal.com/10056.html v1.032] and cpasjuste's [https://github.com/Cpasjuste/dreamboot DreamBoot]. {{DCWiki:Stub}} c847a4ea890981ba2076af6cd2c6c915bcd2e191 Dcload-ip 0 23 728 531 2020-02-11T17:53:36Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip v1.04] - maintained by SiZious * [https://github.com/Moopthehedgehog/dcload-ip dcload-ip v1.05 + DHCP] - maintained by Moopthehedgehog {{DISPLAYTITLE:dcload-ip}} 5dc3165adfd0966e1778bc90851e5054c24ede80 757 728 2020-02-19T05:58:11Z Unknown user 0 fix spelling of SiZiOUS, remove version numbers since they change. wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip main repository] - maintained by SiZiOUS * [https://github.com/Moopthehedgehog/dcload-ip dcload-ip experimental development (also has prebuilt images and binaries)] - maintained by Moopthehedgehog {{DISPLAYTITLE:dcload-ip}} c9748da79ac3be497ebf6b9573e39bc38b21c84e 758 757 2020-02-19T06:03:35Z Unknown user 0 More description wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. The program is mostly intended for homebrew development, but can also be used with special programs designed to make use of it like [https://github.com/zeldin/dc-virtcd Marcus Comstedt's dc-virtcd]. '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip main repository] - maintained by SiZiOUS * [https://github.com/Moopthehedgehog/dcload-ip dcload-ip experimental development (also has prebuilt images and binaries)] - maintained by Moopthehedgehog {{DISPLAYTITLE:dcload-ip}} 56b4b29c49dee8626a393e9e365c558ef69d3b82 File:150-000105-1e SegaDreamcast.pdf 6 250 729 2020-02-11T19:27:52Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Sega Dreamcast Electronic Game Performance and Design Analysis by Portelligent}} |date=2020-02-11 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} dafa5d57585b242681ee24407a532973e76e0248 Hardware overview 0 38 730 632 2020-02-11T19:28:49Z Unknown user 0 wikitext text/x-wiki *'''CPU''': Hitachi SuperH SH7750 SH-4 RISC CPU @ 200MHz **200 MHz/360 MIPS at 3.3V I/O, 1.8V internal **16 x 32-bit general purpose registers **32 x 32-bit single-precision floating point registers **16-bit fixed instruction length for high code density **5 stage pipeline **On-chip cache, 8KB instruction and 16KB data *'''GPU''': NEC PowerVR2 with 8MB of [[VRAM|texture memory]] *'''Sound''': Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memory''': 16MB system memory *'''Storage''': [[GD-ROM drive]] *'''Network''': 33.6K or 56K [[Modem|modem]] [[File:150-000105-1e SegaDreamcast.pdf|thumb|Sega Dreamcast Electronic Game Performance and Design Analysis by Portelligent]] fcf012fd085695feac9a94da75ada04d0444f429 731 730 2020-02-11T19:29:04Z Unknown user 0 wikitext text/x-wiki *'''CPU''': Hitachi SuperH SH7750 SH-4 RISC CPU @ 200MHz **200 MHz/360 MIPS at 3.3V I/O, 1.8V internal **16 x 32-bit general purpose registers **32 x 32-bit single-precision floating point registers **16-bit fixed instruction length for high code density **5 stage pipeline **On-chip cache, 8KB instruction and 16KB data *'''GPU''': NEC PowerVR2 with 8MB of [[VRAM|texture memory]] *'''Sound''': Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memory''': 16MB system memory *'''Storage''': [[GD-ROM drive]] *'''Network''': 33.6K or 56K [[Modem|modem]] [[:File:150-000105-1e SegaDreamcast.pdf|Sega Dreamcast Electronic Game Performance and Design Analysis by Portelligent]] 23f953d53fdc5496ecbb2d834071de39d476732f Mission Stick 0 251 732 2020-02-14T23:07:59Z Unknown user 0 Created page with "The '''ASCII Mission Stick''' is a controller peripheral for the Dreamcast primarily intended for flight simulator usage. It features an analog joystick topped with a mouse-li..." wikitext text/x-wiki The '''ASCII Mission Stick''' is a controller peripheral for the Dreamcast primarily intended for flight simulator usage. It features an analog joystick topped with a mouse-like grip with 3 programmable buttons for the user's right hand; two analog buttons mapped to L and R in for the left hand; and A/B/X/Y buttons, a start button, and a D-pad in the center. It also has options for the A/B/X/Y buttons to be set to turbo (rapid fires when a button is held), auto (rapid fires when a button is not held), hold (holds a button down as long as the button is not physically held), and hold-turbo (holds a button down as long as the button is not physically held and rapid fires as long as the button is held). A VMU or memory card can be inserted into the face of the unit. a9bfd37ebb802e17a82171a64ed1f811a918974a Creating a bootable Dreamcast disc 0 252 733 2020-02-16T16:02:23Z Unknown user 0 Created page with "== Workflow == The usual workflow to make self-bootable disc for the [[Dreamcast]] is as follows: * Build your source (usually using [[KOS]]) * Transform your .elf into bina..." wikitext text/x-wiki == Workflow == The usual workflow to make self-bootable disc for the [[Dreamcast]] is as follows: * Build your source (usually using [[KOS]]) * Transform your .elf into binary * Scramble the binary * Build a .iso image from a directory * Transform the .iso into a .cdi image == Linux == This is an example for automating the .cdi image process under Linux. Consider this more like a template as you'll need to edit the paths, names, etc to your own project. #! /bin/sh PROJECT_DIR=$PWD/build PROJECT_NAME="Project_Name" TARGET="main.elf" # Build your program # This assumes that you can properly build your source code. The program main output will be $TARGET make $TARGET # Elf transform sh-elf-objcopy -R .stack -O binary $TARGET output.bin # Scrambling process $KOS_BASE/utils/scramble/scramble output.bin 1ST_READ.bin # Creating a .iso image from a directory # Make sure you have a working [[IP.BIN]] in your current directory. Or change IP.BIN path to wherever you like. # Useful option for mkisofs is *-m* which allow to exclude files from the iso image (useful to remove .git, or some other folder) mkisofs -C 0,11702 -V $PROJECT_NAME -G IP.BIN -r -J -l -o $PROJECT_NAME.iso $DIR # Transform your .iso into a .cdi $KOS_BASE/utils/cdi4dc/cdi4dc $PROJECT_NAME.iso $PROJECT_NAME.cdi a911faa60962d5e71d741893b7fdb0670579025e 734 733 2020-02-16T16:02:51Z Unknown user 0 wikitext text/x-wiki == Workflow == The usual workflow to make self-bootable disc for the [[Dreamcast]] is as follows: * Build your source (usually using [[KallistiOS]]) * Transform your .elf into binary * Scramble the binary * Build a .iso image from a directory * Transform the .iso into a .cdi image == Linux == This is an example for automating the .cdi image process under Linux. Consider this more like a template as you'll need to edit the paths, names, etc to your own project. #! /bin/sh PROJECT_DIR=$PWD/build PROJECT_NAME="Project_Name" TARGET="main.elf" # Build your program # This assumes that you can properly build your source code. The program main output will be $TARGET make $TARGET # Elf transform sh-elf-objcopy -R .stack -O binary $TARGET output.bin # Scrambling process $KOS_BASE/utils/scramble/scramble output.bin 1ST_READ.bin # Creating a .iso image from a directory # Make sure you have a working [[IP.BIN]] in your current directory. Or change IP.BIN path to wherever you like. # Useful option for mkisofs is *-m* which allow to exclude files from the iso image (useful to remove .git, or some other folder) mkisofs -C 0,11702 -V $PROJECT_NAME -G IP.BIN -r -J -l -o $PROJECT_NAME.iso $DIR # Transform your .iso into a .cdi $KOS_BASE/utils/cdi4dc/cdi4dc $PROJECT_NAME.iso $PROJECT_NAME.cdi a149741658d32dc1392f1003a24007436d4916f6 735 734 2020-02-16T16:07:51Z Unknown user 0 wikitext text/x-wiki == Workflow == The usual workflow to make self-bootable disc for the [[Dreamcast]] goes like this. * Build your source (usually using [[KallistiOS]]) * Transform your .elf into binary * Scramble the binary * Build a .iso image from a directory * Transform the .iso into a .cdi image There are other details that could be taken into account: * You can make Audio/Data and Data/Data .cdi files. Both can selfboot, but the files will be organized differently on the physical CD. {{Citation needed}} == Linux == This is an example for automating the .cdi image process under Linux. Consider this more like a template as you'll need to edit the paths, names, etc to your own project. #! /bin/sh PROJECT_DIR=$PWD/build PROJECT_NAME="Project_Name" TARGET="main.elf" # Build your program # This assumes that you can properly build your source code. The program main output will be $TARGET make $TARGET # Elf transform sh-elf-objcopy -R .stack -O binary $TARGET output.bin # Scrambling process $KOS_BASE/utils/scramble/scramble output.bin 1ST_READ.bin # Creating a .iso image from a directory # Make sure you have a working [[IP.BIN]] in your current directory. Or change IP.BIN path to wherever you like. # Useful option for mkisofs is *-m* which allow to exclude files from the iso image (useful to remove .git, or some other folder) mkisofs -C 0,11702 -V $PROJECT_NAME -G IP.BIN -r -J -l -o $PROJECT_NAME.iso $DIR # Transform your .iso into a .cdi $KOS_BASE/utils/cdi4dc/cdi4dc $PROJECT_NAME.iso $PROJECT_NAME.cdi 67912bd7a8c3afec272e6a9318cd15b6202b09a3 739 735 2020-02-16T16:11:59Z Unknown user 0 wikitext text/x-wiki == Workflow == The usual workflow to make self-bootable disc for the [[Dreamcast]] goes like this. * Build your source (usually using [[KallistiOS]]) * Transform your .elf into binary * Scramble the binary * Build a .iso image from a directory * Transform the .iso into a .cdi image There are other details that could be taken into account: * You can make Audio/Data and Data/Data .cdi files. Both can selfboot, but the files will be organized differently on the physical CD. {{Citation needed}} * You'll need to provide a valid [[IP.BIN]], these can be modified to display a logo during the boot screen, apply patches or execute some code. * It is possible to make CDDA compatible images, this process in not currently covered here. == Linux == This is an example for automating the .cdi image process under Linux. Consider this more like a template as you'll need to edit the paths, names, etc to your own project. #! /bin/sh PROJECT_DIR=$PWD/build PROJECT_NAME="Project_Name" TARGET="main.elf" # Build your program # This assumes that you can properly build your source code. The program main output will be $TARGET make $TARGET # Elf transform sh-elf-objcopy -R .stack -O binary $TARGET output.bin # Scrambling process $KOS_BASE/utils/scramble/scramble output.bin 1ST_READ.bin # Creating a .iso image from a directory # Make sure you have a working [[IP.BIN]] in your current directory. Or change IP.BIN path to wherever you like. # Useful option for mkisofs is *-m* which allow to exclude files from the iso image (useful to remove .git, or some other folder) mkisofs -C 0,11702 -V $PROJECT_NAME -G IP.BIN -r -J -l -o $PROJECT_NAME.iso $DIR # Transform your .iso into a .cdi $KOS_BASE/utils/cdi4dc/cdi4dc $PROJECT_NAME.iso $PROJECT_NAME.cdi 05ffe33b113882d41a4ce315e63e86a2e7cb2360 Template:Citation needed 10 253 736 2020-02-16T16:08:09Z Unknown user 0 Created page with "<small>[[ Citation needed ]]</small>" wikitext text/x-wiki <small>[[ Citation needed ]]</small> e1affb06afbefa4eb0914e6f9671d50373b591b6 737 736 2020-02-16T16:09:14Z Unknown user 0 wikitext text/x-wiki <small>Citation needed</small> dc4ccf6b07eadcc9f4758e99ff104579df48d09d 738 737 2020-02-16T16:10:10Z Unknown user 0 wikitext text/x-wiki <small><sup>Citation needed</sup></small> fd73349a4b4d9f7163ca0ec4709821499f311619 Engine & Library 0 27 740 577 2020-02-17T08:43:59Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is an adaptation of the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by [[SiZiOUS]] * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. * [[libronin]] - an independent development library created by the DreamSNES team ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) f6dec5bb35f4e0f73d860eabbc16444bc79822f3 747 740 2020-02-17T08:49:21Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is an adaptation of the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by [[User:SiZiOUS]] * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. * [[libronin]] - an independent development library created by the DreamSNES team ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 98110d95c9bb2b76f98a37bf8dc80499bcd908d5 748 747 2020-02-17T08:49:38Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is an adaptation of the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by [[User:SiZiOUS]](SiZiOUS) * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. * [[libronin]] - an independent development library created by the DreamSNES team ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) c440ae2f1f84a302b69d365158dae010d47bea19 749 748 2020-02-17T08:50:12Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} This list is an adaptation of the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ## Tutorial * [Dreamcast.wiki](https://dreamcast.wiki) - A brand new wiki with up-to-date information about the Dreamcast. * [DCEmu Developement Wiki](https://dcemulation.org/index.php?title=Development) - Great resource to start. Somewhat incomplete in certain aspect. * [Dreamcast-tutorial Github](https://github.com/dreamcastdevs/dreamcast_tutorial) - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ## Framework * [KOS](https://sourceforge.net/projects/cadcdev/) - The pseudo-OS that's been used in a lot of homebrew/indie. * [DreamSDK](https://www.dreamsdk.org) - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) * [BennuGD](http://wiki.bennugd.org/index.php?title=Bennu_Wiki) - A multi-platform engine * [WincastCE](https://github.com/FaucetDC/WincastCE) - An experimental windows CE shell (?) * [DreamShell](https://github.com/DC-SWAT/DreamShell) - The popular alternative operating system for loading games/app from SD Card and IDE Drive * [LibGyro](http://elysianshadows.com) - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. * [[libronin]] - an independent development library created by the DreamSNES team ## Engine * [Simulant](https://simulant-engine.appspot.com) - A general purpose 2D-3D engine in active developement. * [[nuQuake]] - Quake engine by MrNeo240 * [radQuake](https://github.com/ianmicheal/Radquakemax) - Quake engine by Ian Micheal * [DreamBOR - unofficial](https://github.com/ianmicheal/Dreambor6.0) - OpenBOR dreamcast port forked an improved by Ian Michael * [DolmexicaInfinite](https://github.com/CaptainDreamcast/DolmexicaInfinite) - A Mugen-like engine for fighter games * [Elysian Shadows Toolkit](http://elysianshadows.com) - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ## Graphics * [GLdc](https://gitlab.com/simulant/GLdc) - A OpenGL 1.2 implementation started by Kazade * [LMP3D](https://github.com/Kannagi/LMP3D) - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) * [DreamROQ](https://github.com/multimediamike/dreamroq) - A ROQ video player. (*Stable, no sound*) ## Audio * [ALdc](https://gitlab.com/simulant/ALdc) - A OpenAL 1.2 implementation started by Kazade ## VMU * [CrayonUtil](https://github.com/Protofall/Crayon-Utilities) - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ## Utilities * [Prism](https://github.com/CaptainDreamcast/prism) - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ## Memory Management ## Debugging ## Random * [Homebrew Tests (Protofall)](https://github.com/Protofall/Homebrew-Tests) 1ad5b0f1af2aec2699bf88f8c679f1f0f008d79d User:Speud 2 254 741 2020-02-17T08:44:31Z Unknown user 0 Created page with "Hello! ♥" wikitext text/x-wiki Hello! ♥ 5e73ab62da5333e8c3115e4a9a570d221320b26c 743 741 2020-02-17T08:45:55Z Unknown user 0 wikitext text/x-wiki (Delete Me!) 7f81265da372cb9c25277edfc225768fd79b3f6c 744 743 2020-02-17T08:47:31Z Unknown user 0 SiZiOUS moved page [[SiZiOUS]] to [[User:Speud]] wikitext text/x-wiki (Delete Me!) 7f81265da372cb9c25277edfc225768fd79b3f6c 746 744 2020-02-17T08:48:35Z Unknown user 0 wikitext text/x-wiki Speud is the creator of DreamExplorer/VMU Tool. d1343ec3d22aeec3474735d8a500adb2602f3b00 User:SiZiOUS 2 255 742 2020-02-17T08:45:27Z Unknown user 0 Created page with "Hello! ♥" wikitext text/x-wiki Hello! ♥ 5e73ab62da5333e8c3115e4a9a570d221320b26c System Disc 2 0 19 750 55 2020-02-18T16:09:35Z Unknown user 0 wikitext text/x-wiki The '''System Disc 2''' is a unique disc which, upon being read by the [[GD-ROM drive]], will unlock the Dreamcast's [[GD-ROM]] media security check, allowing one to access and play games on [[GD-R]] media. It is the successor to the "System Disc" CD-ROM that was originally used for similar purposes on the Sega Saturn console. The System Disc 2 also has hidden functionality: if the user connects a controller to port D and holds the Y button as the software loads, a menu will appear that allows the user to view the console's [[BIOS|bootROM]] version string as well as an IP.BIN header viewer that can validate the header and display the flags set on the inserted disc. d788f42c4de665ac801898b535b50352ff6278db Check-GD 0 257 751 2020-02-18T17:41:43Z Unknown user 0 Created page with "There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant ver..." wikitext text/x-wiki There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant versions of the software intended for different use cases. =Known pressed & labelled GD-ROMs= *'''SDPS-1''': Loop Checker / 1.00 / SEGA CS / 01/06/2000 ('''dumped''') *'''SDPS-2''': Unknown ('''undumped''') *'''SDPS-3''': DC checker for REPAIR / 2.15R / CS.R&D / 01/12/2000 ('''undumped''') *'''SDPS-4''': DC checker for MP / 2.16M / CS / 02/02/2000 ('''dumped''') *'''SDPS-5''': DC checker for REPAIR / 2.16R / CS / 02/02/2000 *'''SDPS-6''': Unknown ('''undumped''') *'''SDPS-7''': Himozuke Family / 2.40 / CS / 07/14/2000 ('''undumped''') *Internal Printing Disc (HKT-999999) - ('''undumped''') No images available, believed to be the same software as GD Drive Repair Program silver disc? =Known pressed silvers= *DC Checker for Repair v2.05R (DCSC205R) ('''dumped''') *GD Drive Repair Program 0.1 (DCGD01) ('''dumped''') 03d21b526b07d356069f45e11d42e540b69b22c4 754 751 2020-02-18T18:23:10Z Unknown user 0 wikitext text/x-wiki There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant versions of the software intended for different use cases. =Known pressed & labelled GD-ROMs= *'''SDPS-1''': Loop Checker / 1.00 / SEGA CS / 01/06/2000 ('''dumped''') *'''SDPS-2''': Unknown ('''undumped''') *'''SDPS-3''': DC checker for REPAIR / 2.15R / CS.R&D / 01/12/2000 ('''undumped''') *'''SDPS-4''': DC checker for MP / 2.16M / CS / 02/02/2000 ('''dumped''') *'''SDPS-5''': DC checker for REPAIR / 2.16R / CS / 02/02/2000 ('''undumped''') *'''SDPS-6''': Unknown ('''undumped''') *'''SDPS-7''': Himozuke Family / 2.40 / CS / 07/14/2000 ('''undumped''') *Internal Printing Disc (HKT-999999) - ('''undumped''') No images available, believed to be the same software as GD Drive Repair Program silver disc? =Known pressed silvers= *DC Checker for Repair v2.05R (DCSC205R) ('''dumped''') *GD Drive Repair Program 0.1 (DCGD01) ('''dumped''') ==Console bricking risk== During the test process, the console flashROM is subject to both read and write tests, which result in the flashROM being completely erased (along with all console settings, ISP settings, [[Phantasy Star Online]] serial number & access code, etc.). This will not cause issues on a stock console, however, if the console has been modified with the [[region change]] mod and the write-enable wire has not been removed, the console's region coding will be erased and the console will no longer boot any software unless the flashROM is repaired or a region-free BIOS is installed. ==Hidden options== There are multiple modes that the disc can be run in depending on what buttons you hold down at the IP.BIN screen: *Holding nothing: Full checker *Holding A + B: Full checker but without modem checks, req. for Asian modemless consoles to pass *Holding X + Down on D-Pad: MP Checker mode, skips critical tests but runs the other tests *Holding X + Right on D-Pad: Single test mode, disables test script and allows you to scroll through the individual tests and pick them at will *Holding Y + Up on D-Pad: CLX Signature check, which renders a scene and compares calculated graphics data against reference data *Holding Y + Right: CLX Signature Aging test, which performs the above test repeatedly on a loop. This test is available with and without a GD drive seek test included in the test loop. *Holding Y + Down on D-Pad: Sonic Cube mode, which allows you to run several Holly samples, basically the same ones that are run during the scripted test modes, but you can control them with controller. **Non-Tex Cube **Tex Cube **Punch-Thru Cube (X+Up/Down increases/decreases number of cubes, Y+Up/Down zooms in and out, start pauses/resumes motion) **Vertex Test (B toggles mirror map and transparency, d-pad moves screen) **Torus test (A changes number of doughnuts, Y+Up/Down zooms in/out, start pauses/resumes motion) *Holding X + Left: FlashROM viewer mode, which displays information about the console stored in the FlashROM (serial number, factory codes, etc.) *Holding X + Up: Katana Set5 checker mode, which runs the same diagnostic tests as those built into the BIOS of the Katana Set5 *Holding A + B + X + Down: Address checker mode, which displays a blank screen but allows the user to control a "tiny address checker" program via serial link 5e84b8476e5f5b0843d8e44ca0c008e6861382d5 755 754 2020-02-18T18:23:40Z Unknown user 0 wikitext text/x-wiki There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant versions of the software intended for different use cases. =Known pressed & labelled GD-ROMs= *'''SDPS-1''': Loop Checker / 1.00 / SEGA CS / 01/06/2000 ('''dumped''') *'''SDPS-2''': Unknown ('''undumped''') *'''SDPS-3''': DC checker for REPAIR / 2.15R / CS.R&D / 01/12/2000 ('''undumped''') *'''SDPS-4''': DC checker for MP / 2.16M / CS / 02/02/2000 ('''dumped''') *'''SDPS-5''': DC checker for REPAIR / 2.16R / CS / 02/02/2000 ('''undumped''') *'''SDPS-6''': Unknown ('''undumped''') *'''SDPS-7''': Himozuke Family / 2.40 / CS / 07/14/2000 ('''undumped''') *Internal Printing Disc (HKT-999999) - ('''undumped''') No images available, believed to be the same software as GD Drive Repair Program silver disc? =Known pressed silvers= *DC Checker for Repair v2.05R (DCSC205R) ('''dumped''') *GD Drive Repair Program 0.1 (DCGD01) ('''dumped''') ==Hidden options== There are multiple modes that the disc can be run in depending on what buttons you hold down at the IP.BIN screen: *Holding nothing: Full checker *Holding A + B: Full checker but without modem checks, req. for Asian modemless consoles to pass *Holding X + Down on D-Pad: MP Checker mode, skips critical tests but runs the other tests *Holding X + Right on D-Pad: Single test mode, disables test script and allows you to scroll through the individual tests and pick them at will *Holding Y + Up on D-Pad: CLX Signature check, which renders a scene and compares calculated graphics data against reference data *Holding Y + Right: CLX Signature Aging test, which performs the above test repeatedly on a loop. This test is available with and without a GD drive seek test included in the test loop. *Holding Y + Down on D-Pad: Sonic Cube mode, which allows you to run several Holly samples, basically the same ones that are run during the scripted test modes, but you can control them with controller. **Non-Tex Cube **Tex Cube **Punch-Thru Cube (X+Up/Down increases/decreases number of cubes, Y+Up/Down zooms in and out, start pauses/resumes motion) **Vertex Test (B toggles mirror map and transparency, d-pad moves screen) **Torus test (A changes number of doughnuts, Y+Up/Down zooms in/out, start pauses/resumes motion) *Holding X + Left: FlashROM viewer mode, which displays information about the console stored in the FlashROM (serial number, factory codes, etc.) *Holding X + Up: Katana Set5 checker mode, which runs the same diagnostic tests as those built into the BIOS of the Katana Set5 *Holding A + B + X + Down: Address checker mode, which displays a blank screen but allows the user to control a "tiny address checker" program via serial link ==Console bricking risk== During the test process, the console flashROM is subject to both read and write tests, which result in the flashROM being completely erased (along with all console settings, ISP settings, [[Phantasy Star Online]] serial number & access code, etc.). This will not cause issues on a stock console, however, if the console has been modified with the [[region change]] mod and the write-enable wire has not been removed, the console's region coding will be erased and the console will no longer boot any software unless the flashROM is repaired or a region-free BIOS is installed. 561840b0288786c3f8669137ad2dfd4f4d35faef DC Checker 0 258 752 2020-02-18T18:04:37Z Unknown user 0 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 753 752 2020-02-18T18:05:24Z Unknown user 0 Redirected page to [[Check-GD]] wikitext text/x-wiki #REDIRECT [[Check-GD]] 21a38ff2b7eec537cab70ddb71b22d0b6ba023c7 Broadband adapter 0 5 756 725 2020-02-19T05:54:53Z Unknown user 0 It doesn't do CDI, just bin and elf (and srec, if configured for it with bfd; not true by default) wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from Sega Direct in Japan. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) {{DCWiki:Stub}} == References == c330df53aae38ede2da2b59ea95b6ae1d4a51801 Freeware homebrew games 0 76 759 216 2020-02-20T18:02:54Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Space Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[ArmoredCampaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[Clone Keen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[SonicRoboBlast2|Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 45dc16c6c375424df0a071eadc0dd3e739c5e8e6 Galaga 0 259 760 2020-02-20T18:08:25Z Unknown user 0 Page addition - IMR Galaga, in sbi format only (so far) wikitext text/x-wiki ## Description A port of Galaga made by IMRTechnologies/Ian Micheal. **Type** : Shooting Game **Website** : Unknown **Release Date** : Unknown ## Technical * Currently only available in .sbi format 311cef3afb1ae1986f53cc47c3ce74340fb0f214 761 760 2020-02-20T18:09:32Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Description A port of Galaga made by IMRTechnologies/Ian Micheal. **Type** : Shooting Game **Website** : Unknown **Release Date** : Unknown ## Technical * Currently only available in .sbi format 01db098429b940019fcfb75023b901b3a799a1d9 763 761 2020-02-20T18:53:04Z Unknown user 0 wikitext text/x-wiki {{MARKDOWN}} ## Description A port of Galaga made by IMRTechnologies/Ian Micheal. **Type** : Shooting Game **Website** : Unknown **Release Date** : Unknown **Download** : [[File:Galaga - SBI version.sbi|thumb|Galaga homebrew game in .sbi format . made by IMRTechnologies]] ## Technical * Currently only available in .sbi format dfa99f3ceb18de8baa937fc3d2ca568bf0b79d09 File:Galaga - SBI version.sbi 6 260 762 2020-02-20T18:51:45Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Galaga homebrew game in .sbi format . made by IMRTechnologies}} |date=2020-02-20 |source={{own}} |author=[[User:I.M. Weasel|I.M. Weasel]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} [[Category:Game]] [[Category:Homebrew]] [[Category:Sbi]] 710dc7f75727c9bf6a7a008d57f1402f6448125f Development 0 2 764 688 2020-02-21T22:17:23Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[About the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby on Sega Dreamcast]] (experimental) === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] d0b6dda0dc1fedf522fbfc10be3288141d14370a 765 764 2020-02-21T22:18:41Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[About the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Setting up Ruby for Sega Dreamcast development]] (experimental) === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 95596839fb5abb538efdb001839b1d7bd6059e94 766 765 2020-02-21T22:20:00Z Unknown user 0 /* Getting Started */ wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Setting up Ruby for Sega Dreamcast development]] (experimental) === Build & test === * Building your project * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial * Disc === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] a4ab1cbda1f550052535f6898fedeed5f22c8524 767 766 2020-02-21T22:23:29Z Unknown user 0 Plan of the page wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Setting up Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] b3f66544f7798b3311ac96980a8b2f9fabd8d13d 768 767 2020-02-21T22:24:31Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Setting up Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 51521048b5e96f34673e0785453bac53b8344aed 769 768 2020-02-21T22:26:10Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 3876c4f40ff2010f142d53b25d19eaa6b216ef44 770 769 2020-02-21T22:26:33Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband Adapter]] ** [[Linux : BBA with dcload-ip]] * Serial === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 095a70120aa266179c33a21051492fe0e8644a71 771 770 2020-02-21T22:27:04Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] ** [[Linux : BBA with dcload-ip]] * Serial === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 3876c4f40ff2010f142d53b25d19eaa6b216ef44 772 771 2020-02-21T22:27:56Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN_adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coders Cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] b85c4953bd6b37bc009e546b746afa944c64ebbd 773 772 2020-02-21T22:28:24Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coders cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] bb6724da3a31cd8481981913a14d067353e660d6 775 773 2020-02-21T22:42:10Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Introduction on Sega Dreamcast development]] * [[Ready-to-use environments]] ** [[DreamSDK]] (Windows only) ** Docker images * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 7f4b97d65ea22c2962cdba0a51c91b82c88b3f6e 776 775 2020-02-22T11:44:08Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** Docker images ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 405b3b4c38d6a7dac285b95b29658ac841ebf6b1 Building the required toolchains for Sega Dreamcast development 0 261 774 2020-02-21T22:38:18Z Unknown user 0 Created page with "== DRAFT == In order to develop for the Sega Dreamcast console, you will need 3 different toolchains: * A sh-elf toolchain, which is the main toolchain. It targets the CPU of..." wikitext text/x-wiki == DRAFT == In order to develop for the Sega Dreamcast console, you will need 3 different toolchains: * A sh-elf toolchain, which is the main toolchain. It targets the CPU of the Dreamcast, i.e. the Hitachi SH-4 CPU (SuperH). * An arm-eabi toolchain, which is the toolchain used only for the Yamaha Super Intelligent Sound Processor (AICA). This processor is based on an ARM7 core. * The host toolchain from your computer in order to produce some additional tools (i.e. the regular gcc of your computer). The sh-elf and arm-eabi toolchains may be produced by the dc-chain tool provided with KallistiOS. This package contains a Makefile which both simplifies building the whole Sega Dreamcast toolchain, and gives you substantial control. The toolchain is composed by: The dc-chain Makefile is ready to build everything you need to compile KallistiOS and then develop for the Sega Dreamcast system. About toolchain components versions Components that are included in a toolchain are: * Binutils (mainly ld plus other tools) * GNU Compiler Collection (gcc) * Newlib (mainly libc plus other libraries) * GNU Debugger (gdb) - Optional As we are building two toolchains (sh-elf and arm-eabi), all these components will be installed twice, for both targets. Speaking about the best versions to use for the Sega Dreamcast development, they are already declared in the Makefile. This is particulary true for gcc: the best version to use at this time is the 4.7.3. We know that today this version is pretty old but greater versions have serious issues so it's better to stick with that version. Plus, gcc's bugtracker has a lot of bugs marked as [6/7/8/9 Regression] for the sh-elf target which have not been resolved. Newer isn't always better, especially with gcc targets that aren't high-priority. Advanced options You may attempt to spawn multiple jobs with make. Using make -j4 is recommended for speeding up the building of the toolchain. There is an option inside the Makefile to set the number of jobs for the building phases. Set the makejobs variable in the Makefile to whatever you would normally feel the need to use on the command line, and it will do the right thing. In the old times, this option may breaks things, so, if you run into trouble, you should clear this variable and try again with just one job running. On MinGW/MSYS environment, it has been confirmed that multiple jobs breaks the toolchain, so please don't try to do that under this environment. This option is disabled by default in this scenario. This doesn't apply to the others environments, including MinGW-w64/MSYS2. Usage Before you start, please browse the ./doc directory and check if they are full instructions for building the whole toolchain for your environment. Making the toolchain Below you will find some generic instructions: Change the variables in the User Configuration section of the Makefile to match your environment. They can be overridden at the command line as well. Please note, a lot of conditional instructions have been added, so it should work most of the time just out-of-the-box for your environment. Then execute the following for preparing the sources: ./download.sh ./unpack.sh Finally, input (for BSD, please use gmake instead): make Depending of your environment, this can take a bunch of hours. So please be patient! If anything goes wrong, check the output in logs/. Making the GNU Debugger (gdb) For the sh-elf toolchain, if you want to use the GNU Debugger (gdb), you can make it by entering: make gdb This will install gdb in the sh-elf toolchain (gdb is used with dcload/dc-tool programs, which are part of KallistiOS too). Removing all useless files After the toolchain compilation, you can cleanup everything by entering: ./cleanup.sh This will save a lot of space. Final note Please see the comments at the top of the Makefile for more build options. 05b9517d522d2f18fe13eb1403b639a74877b729 Using Ruby for Sega Dreamcast development 0 262 777 2020-02-22T13:52:25Z Unknown user 0 /* Draft */ wikitext text/x-wiki It's possible to develop in Ruby for the Sega Dreamcast using the mruby implementation. The proof-of-concept was made by [[Yuji Yokoo]] back in 2019. This is experimental and a lot of features are missing/not working/not tested (e.g. debugging). == Prerequisites == You should have a working [[KallistiOS]] environment. Also you need to have rake and bison installed. === Installing prerequisites on MinGW/MSYS === Install RubyInstaller (if XP : 2.0.0) then add it to the path. Install bison in the MinGW Get program === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Shell and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb /opt/mruby/build_config.rb make This will generate all the required files, the -lmruby is now available 96a62f843bbd0c58c742cf04adf626cdca5a6233 Using Ruby for Sega Dreamcast development 0 262 778 777 2020-02-23T10:21:23Z Unknown user 0 /* Setting up mruby */ wikitext text/x-wiki It's possible to develop in Ruby for the Sega Dreamcast using the mruby implementation. The proof-of-concept was made by [[Yuji Yokoo]] back in 2019. This is experimental and a lot of features are missing/not working/not tested (e.g. debugging). == Prerequisites == You should have a working [[KallistiOS]] environment. Also you need to have rake and bison installed. === Installing prerequisites on MinGW/MSYS === Install RubyInstaller (if XP : 2.0.0) then add it to the path. Install bison in the MinGW Get program === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Shell and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, the -lmruby is now available 910c34e9d2fd614e09b5779e5e77064652026099 779 778 2020-02-23T17:04:15Z Unknown user 0 Major refactoring of the page wikitext text/x-wiki Since 2019, it's now possible to develop in Ruby for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. The proof-of-concept was made by [[Yuji Yokoo]]. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS). == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * the ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS). * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). 46baadf26b7f1e0cfabd6106221290ec757738b9 780 779 2020-02-23T17:04:47Z Unknown user 0 Adding Ruby link wikitext text/x-wiki Since 2019, it's now possible to develop in [https://www.ruby-lang.org Ruby] for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. The proof-of-concept was made by [[Yuji Yokoo]]. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS). == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * the ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS). * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). e7b6bdf6689be9149d8de8f0bc5b598d1dd375a9 781 780 2020-02-23T17:05:14Z Unknown user 0 Some modification in intro wikitext text/x-wiki Since 2019, it's now possible to develop in [https://www.ruby-lang.org Ruby] for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. The proof-of-concept was made by [[Yuji Yokoo]]. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS) as base. == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * the ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS). * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). d5f699249300200ca28ce9c7dbb6a260a9680024 782 781 2020-02-23T17:06:02Z Unknown user 0 wikitext text/x-wiki Since 2019, it's now possible to develop in [https://www.ruby-lang.org Ruby] for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. The proof-of-concept was made by [[Yuji Yokoo]]. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS) as base. == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * the ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS) - this is actually an issue that should be resolved later; * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). d2da03313d0e6f7da172ce096db67cb50cb14092 783 782 2020-02-23T17:06:37Z Unknown user 0 Typo fix wikitext text/x-wiki Since 2019, it's now possible to develop in [https://www.ruby-lang.org Ruby] for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. The proof-of-concept was made by [[Yuji Yokoo]]. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS) as base. == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * the ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS) - this is actually an issue that should be fixed later; * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). 1d2faef3588adf25f6c93acf7c24f30acd197624 794 783 2020-03-07T22:21:17Z Unknown user 0 Fixing introduction wikitext text/x-wiki It's possible to develop in [https://www.ruby-lang.org Ruby] for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. This proof-of-concept was initially made by [[Yuji Yokoo]] back in 2019. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS) as base. == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * The ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS) - this is actually an issue that should be fixed later; * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby cp examples/targets/build_config_dreamcast_shelf.rb build_config.rb make This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). 5d6e58fe2561460acfbd664a0c70b97d5392afa7 DCDigital 0 14 784 487 2020-02-26T13:18:30Z Unknown user 0 wikitext text/x-wiki '''DCDigital''' (formerly known as '''DCHDMI''') is a modification kit created by chriz2600 and citrus3000psi which adds native digital audio and video (via HDMI output) to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. All current hardware modifications, such as overclocking, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCDigital. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Links === * [http://www.dansprojects.com/dchdmi_install.html Installation instructions] * DCHDMI Installation video: [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * [https://dc.i74.de/ Latest firmware] {{DCWiki:Stub}} 44c36c5f6fad6389e8824bffdf18faed93464729 785 784 2020-02-26T13:18:50Z Unknown user 0 Darc moved page [[DCHDMI]] to [[DCDigital]]: DCHDMI project renamed to DCDigital wikitext text/x-wiki '''DCDigital''' (formerly known as '''DCHDMI''') is a modification kit created by chriz2600 and citrus3000psi which adds native digital audio and video (via HDMI output) to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. All current hardware modifications, such as overclocking, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCDigital. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Links === * [http://www.dansprojects.com/dchdmi_install.html Installation instructions] * DCHDMI Installation video: [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * [https://dc.i74.de/ Latest firmware] {{DCWiki:Stub}} 44c36c5f6fad6389e8824bffdf18faed93464729 788 785 2020-02-26T13:19:45Z Unknown user 0 wikitext text/x-wiki '''DCDigital''' (formerly known as '''DCHDMI''') is a modification kit created by chriz2600 and citrus3000psi which adds native digital audio and video (via HDMI output) to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. All current hardware modifications, such as overclocking, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCDigital. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Links === * [http://www.dansprojects.com/dchdmi_install.html Installation instructions] * DCDigital Installation video: [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * [https://dc.i74.de/ Latest firmware] {{DCWiki:Stub}} e2e8f2a4f328534e38cf50e31cd3de13a74ecf71 799 788 2020-03-07T23:15:21Z Unknown user 0 wikitext text/x-wiki '''DCDigital''' (formerly known as '''DCHDMI''') is a modification kit created by chriz2600 and citrus3000psi which adds native digital audio and video (via HDMI output) to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. Both the hardware design and the firmware are open source, allowing anyone to legally clone the mod kit. * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. All current hardware modifications, such as overclocking, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCDigital. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Links === * [http://www.dansprojects.com/dchdmi_install.html Installation instructions] * DCDigital Installation video: [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * [https://dc.i74.de/ Latest firmware] * [https://github.com/citrus3000psi/DCHDMI-Hardware Hardware design files] on github * [https://github.com/chriz2600/DreamcastHDMI/ Firmware source code] on github {{DCWiki:Stub}} 56e82df52fd19a9e519b06cb07f1b52007c0e555 DCHDMI 0 263 786 2020-02-26T13:18:50Z Unknown user 0 Darc moved page [[DCHDMI]] to [[DCDigital]]: DCHDMI project renamed to DCDigital wikitext text/x-wiki #REDIRECT [[DCDigital]] 54e8b13f1b14911421b1c95c9bbae7ed8790d9dd DCWiki:Hardware 4 82 787 420 2020-02-26T13:19:26Z Unknown user 0 /* Hardware */ wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCDigital]] (formerly DCHDMI), [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} 4d3535baff6685ccf46116ed8933fcfea161c58a Using dcload-ip with Windows Subsystem for Linux 0 264 789 2020-02-27T23:13:23Z Unknown user 0 Created page with "{{MARKDOWN}} # WSL v2 : using dcload-ip with the BBA from WSL and Windows This tutorial has been tested on Windows 10 Insider Preview and Windows Subsystem for Linux (WSL) v2...." wikitext text/x-wiki {{MARKDOWN}} # WSL v2 : using dcload-ip with the BBA from WSL and Windows This tutorial has been tested on Windows 10 Insider Preview and Windows Subsystem for Linux (WSL) v2. My Dreamcast is connected directly to a router that is also connected to my computer, the router is not plugged into anything else, and does not having greater network access, and using dcload-ip with a hardcoded static IP address. ## Dreamcast side Get a selfbooting version of [dc-load-ip (in the "Releases" section)](https://github.com/Moopthehedgehog/dcload-ip). I've burned this with [imgburn](https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/) without any problem. Next, boot **dc-load-ip** in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green/blue screen appears (depending on version, moop: green, standard: blue), note down your MAC address. It should look something like : `10:04:5d:2b:0f:4d` ## Computer side (not necessary if using pre-built DHCP version) We'll use the arp function to get your computer to "give" an IP address to your Dreamcast based on its mac address. ### Under a Windows Terminal First we need Administrator access to add an arp entry ``Start-Process PowerShell –Verb RunAs`` After you have this PowerShell instance open we will add our entry ``New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "[local IP address]" -LinkLayerAddress "[MAC address]"`` - If using Wifi, the interface alias is likely ``"Wi-Fi"`` This is the command I use ``New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F"`` This should be fairly straightword to modify for your needs and network setup. This will be a permanent addition which will persist across restarts and shutdowns. Expected Output: ``` PS C:\WINDOWS\system32> New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F" ifIndex IPAddress LinkLayerAddress State PolicyStore ------- --------- ---------------- ----- ----------- 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent ActiveStore 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent PersistentStore ``` ## Notes `[local IP address]` is any valid IP address that you want to assign to your Dreamcast `[MAC address]` is your dreamcast's MAC address, look at step 2. the local IP address should be in the same range as your network. In my setup, my ethernet port is set on port 192.168.5.100 and my `[local IP address]` is 192.168.5.99. If you don't know your network range, you can use `ifconfig` in a terminal to find out. I wont cover this here. ## The following can be executed from within Windows or WSL (Linux) At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. `ping [local IP address]` you should get a message like : 64 byte from [local IP address] .... blabla ... time=xx ms ### Testing your code You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running **dc-load-ip**. `dc-tool-ip -t [local IP address] -x /path/to/your/.bin/or/.elf/file` You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the `/pc` path. ## Notes (for non-DHCP use) ### Adding a host name (Linux) Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. `sudo nano /etc/hosts` then adding the line : `dreamcast [local IP address]` ### Adding a host name (Windows) 1. Press the Windows key. 1. Type Notepad in the search field. 1. In the search results, right-click Notepad and select Run as administrator. 1. From Notepad, open the following file: ``c:\Windows\System32\Drivers\etc\hosts`` 1. Add a new entry to the file. 2. eg. `dreamcast [local IP address]` on a newline 3. Select File > Save to save your changes. You can now refer do `dreamcast` instead of your usual `[local IP adress]` _Other info at [CubicVR](https://github.com/cjcliffe/CubicVR/wiki/Dreamcast:-dc-load-ip)_ 71eb2c54f722fcc56cc1172224f18dea44ffa320 File:Spec-8139c(160).pdf 6 265 790 2020-02-28T17:19:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=Realtek RTL8139C datasheet}} |date=2005-12-29 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 6e2e61dcbb62a1ff1d29ea7bb1db57f1573b8d2c Broadband adapter 0 5 791 756 2020-02-28T17:19:57Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from Sega Direct in Japan. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] {{DCWiki:Stub}} == References == 1ca98bedada4cba766782fed0e0d2ebc3b09d8fa 792 791 2020-02-28T17:20:09Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from Sega Direct in Japan. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == a34b5789836133f0ae4856ca925e7c3676a6a384 Tools and Utilities 0 131 793 462 2020-03-05T22:59:09Z Unknown user 0 /* CD utilities */ wikitext text/x-wiki This article will list various tools and utilities for Dreamcast development and game hacking. == CD utilities == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[dcdis]] || || |- | [[mkisofs]] || Bundle your project directory into a .iso || |- | [[cdi4dc]] || Create bootable .CDI files || |- | [[img4dc]] || Updated version of cdi4dc || |- | [[GD-ROM Explorer]] || Extract and manipulate GD-ROM images in GDI format || |} == Texture converter == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[Texconv]] || Convert your texture to the .dtex format || [https://github.com/tvspelsfreak/texconv Github] |- | [[Crayon Utilities]] || VMU and RGBA888 image conversion || [https://github.com/Protofall/Crayon-Utilities Github] |} {{DCWiki:Stub}} d5444d2567875f1c427de7dc390f5dfb5d63c682 Building the required toolchains for Sega Dreamcast development 0 261 795 774 2020-03-07T22:30:27Z Unknown user 0 Reformatting page wikitext text/x-wiki In order to produces binaries targetting the Sega Dreamcast hardware, you will need 3 different toolchains: * A ''sh-elf'' toolchain, which will be the main toolchain. It targets the CPU of the Dreamcast, i.e. the Hitachi SH-4 CPU (SuperH). * An ''arm-eabi'' toolchain, which is the toolchain used only for the Yamaha Super Intelligent Sound Processor (AICA). This processor is based on an ARM7 core. It will mainly be used to compile the [[KallistiOS]] sound driver. * The host toolchain from your computer in order to produce some additional tools (i.e. the regular ''gcc'' of your computer). The ''sh-elf'' and ''arm-eabi'' toolchains may be produced by the ''dc-chain'' tool provided with KallistiOS. It's located in the ''utils'' directory. This package contains a ''Makefile'' which both simplifies building the whole Sega Dreamcast toolchain, and gives you substantial control. The dc-chain ''Makefile'' is ready to build everything you need to compile KallistiOS and then develop for the Sega Dreamcast system. == About toolchain components versions == Components that are included in a toolchain are: * '''Binutils''': mainly ld plus other tools; * '''GNU Compiler Collection''' (''gcc''); * '''Newlib''': mainly libc plus other libraries (for ''sh-elf'' only); * '''GNU Debugger''' (''gdb''): (for ''sh-elf'' only). As we are building two toolchains (sh-elf and arm-eabi), all these components will be installed twice, for both targets. Speaking about the best versions to use for the Sega Dreamcast development, they are already declared in the Makefile. This is particulary true for gcc: the best version to use at this time is the 4.7.3. We know that today this version is pretty old but greater versions have serious issues so it's better to stick with that version. Plus, gcc's bugtracker has a lot of bugs marked as [6/7/8/9 Regression] for the sh-elf target which have not been resolved. Newer isn't always better, especially with gcc targets that aren't high-priority. == Advanced options == You may attempt to spawn multiple jobs with make. Using make -j4 is recommended for speeding up the building of the toolchain. There is an option inside the Makefile to set the number of jobs for the building phases. Set the makejobs variable in the Makefile to whatever you would normally feel the need to use on the command line, and it will do the right thing. In the old times, this option may breaks things, so, if you run into trouble, you should clear this variable and try again with just one job running. On MinGW/MSYS environment, it has been confirmed that multiple jobs breaks the toolchain, so please don't try to do that under this environment. This option is disabled by default in this scenario. This doesn't apply to the others environments, including MinGW-w64/MSYS2. == Usage == Before you start, please browse the ./doc directory and check if they are full instructions for building the whole toolchain for your environment. === Making the toolchain === Below you will find some generic instructions: Change the variables in the User Configuration section of the Makefile to match your environment. They can be overridden at the command line as well. Please note, a lot of conditional instructions have been added, so it should work most of the time just out-of-the-box for your environment. Then execute the following for preparing the sources: ./download.sh ./unpack.sh Finally, input (for BSD, please use gmake instead): make Depending of your environment, this can take a bunch of hours. So please be patient! If anything goes wrong, check the output in logs/. === Making the GNU Debugger (gdb) === For the sh-elf toolchain, if you want to use the GNU Debugger (gdb), you can make it by entering: make gdb This will install gdb in the sh-elf toolchain (gdb is used with dcload/dc-tool programs, which are part of KallistiOS too). == Removing all useless files == After the toolchain compilation, you can cleanup everything by entering: ./cleanup.sh This will save a lot of space. == Final note == Please see the comments at the top of the Makefile for more build options. 7f705bad25bacc2499615ecfd3d58e23f09951c1 796 795 2020-03-07T22:30:52Z Unknown user 0 /* Removing all useless files */ wikitext text/x-wiki In order to produces binaries targetting the Sega Dreamcast hardware, you will need 3 different toolchains: * A ''sh-elf'' toolchain, which will be the main toolchain. It targets the CPU of the Dreamcast, i.e. the Hitachi SH-4 CPU (SuperH). * An ''arm-eabi'' toolchain, which is the toolchain used only for the Yamaha Super Intelligent Sound Processor (AICA). This processor is based on an ARM7 core. It will mainly be used to compile the [[KallistiOS]] sound driver. * The host toolchain from your computer in order to produce some additional tools (i.e. the regular ''gcc'' of your computer). The ''sh-elf'' and ''arm-eabi'' toolchains may be produced by the ''dc-chain'' tool provided with KallistiOS. It's located in the ''utils'' directory. This package contains a ''Makefile'' which both simplifies building the whole Sega Dreamcast toolchain, and gives you substantial control. The dc-chain ''Makefile'' is ready to build everything you need to compile KallistiOS and then develop for the Sega Dreamcast system. == About toolchain components versions == Components that are included in a toolchain are: * '''Binutils''': mainly ld plus other tools; * '''GNU Compiler Collection''' (''gcc''); * '''Newlib''': mainly libc plus other libraries (for ''sh-elf'' only); * '''GNU Debugger''' (''gdb''): (for ''sh-elf'' only). As we are building two toolchains (sh-elf and arm-eabi), all these components will be installed twice, for both targets. Speaking about the best versions to use for the Sega Dreamcast development, they are already declared in the Makefile. This is particulary true for gcc: the best version to use at this time is the 4.7.3. We know that today this version is pretty old but greater versions have serious issues so it's better to stick with that version. Plus, gcc's bugtracker has a lot of bugs marked as [6/7/8/9 Regression] for the sh-elf target which have not been resolved. Newer isn't always better, especially with gcc targets that aren't high-priority. == Advanced options == You may attempt to spawn multiple jobs with make. Using make -j4 is recommended for speeding up the building of the toolchain. There is an option inside the Makefile to set the number of jobs for the building phases. Set the makejobs variable in the Makefile to whatever you would normally feel the need to use on the command line, and it will do the right thing. In the old times, this option may breaks things, so, if you run into trouble, you should clear this variable and try again with just one job running. On MinGW/MSYS environment, it has been confirmed that multiple jobs breaks the toolchain, so please don't try to do that under this environment. This option is disabled by default in this scenario. This doesn't apply to the others environments, including MinGW-w64/MSYS2. == Usage == Before you start, please browse the ./doc directory and check if they are full instructions for building the whole toolchain for your environment. === Making the toolchain === Below you will find some generic instructions: Change the variables in the User Configuration section of the Makefile to match your environment. They can be overridden at the command line as well. Please note, a lot of conditional instructions have been added, so it should work most of the time just out-of-the-box for your environment. Then execute the following for preparing the sources: ./download.sh ./unpack.sh Finally, input (for BSD, please use gmake instead): make Depending of your environment, this can take a bunch of hours. So please be patient! If anything goes wrong, check the output in logs/. === Making the GNU Debugger (gdb) === For the sh-elf toolchain, if you want to use the GNU Debugger (gdb), you can make it by entering: make gdb This will install gdb in the sh-elf toolchain (gdb is used with dcload/dc-tool programs, which are part of KallistiOS too). == Removing all useless files == After the toolchain compilation, you can cleanup everything by entering: ./cleanup.sh This will save a lot of space. == Final note == Please see the comments at the top of the Makefile for more build options. 6a0184eebc86a54f9b9418e238443d328f1216d0 797 796 2020-03-07T22:31:09Z Unknown user 0 /* Removing all useless files */ wikitext text/x-wiki In order to produces binaries targetting the Sega Dreamcast hardware, you will need 3 different toolchains: * A ''sh-elf'' toolchain, which will be the main toolchain. It targets the CPU of the Dreamcast, i.e. the Hitachi SH-4 CPU (SuperH). * An ''arm-eabi'' toolchain, which is the toolchain used only for the Yamaha Super Intelligent Sound Processor (AICA). This processor is based on an ARM7 core. It will mainly be used to compile the [[KallistiOS]] sound driver. * The host toolchain from your computer in order to produce some additional tools (i.e. the regular ''gcc'' of your computer). The ''sh-elf'' and ''arm-eabi'' toolchains may be produced by the ''dc-chain'' tool provided with KallistiOS. It's located in the ''utils'' directory. This package contains a ''Makefile'' which both simplifies building the whole Sega Dreamcast toolchain, and gives you substantial control. The dc-chain ''Makefile'' is ready to build everything you need to compile KallistiOS and then develop for the Sega Dreamcast system. == About toolchain components versions == Components that are included in a toolchain are: * '''Binutils''': mainly ld plus other tools; * '''GNU Compiler Collection''' (''gcc''); * '''Newlib''': mainly libc plus other libraries (for ''sh-elf'' only); * '''GNU Debugger''' (''gdb''): (for ''sh-elf'' only). As we are building two toolchains (sh-elf and arm-eabi), all these components will be installed twice, for both targets. Speaking about the best versions to use for the Sega Dreamcast development, they are already declared in the Makefile. This is particulary true for gcc: the best version to use at this time is the 4.7.3. We know that today this version is pretty old but greater versions have serious issues so it's better to stick with that version. Plus, gcc's bugtracker has a lot of bugs marked as [6/7/8/9 Regression] for the sh-elf target which have not been resolved. Newer isn't always better, especially with gcc targets that aren't high-priority. == Advanced options == You may attempt to spawn multiple jobs with make. Using make -j4 is recommended for speeding up the building of the toolchain. There is an option inside the Makefile to set the number of jobs for the building phases. Set the makejobs variable in the Makefile to whatever you would normally feel the need to use on the command line, and it will do the right thing. In the old times, this option may breaks things, so, if you run into trouble, you should clear this variable and try again with just one job running. On MinGW/MSYS environment, it has been confirmed that multiple jobs breaks the toolchain, so please don't try to do that under this environment. This option is disabled by default in this scenario. This doesn't apply to the others environments, including MinGW-w64/MSYS2. == Usage == Before you start, please browse the ./doc directory and check if they are full instructions for building the whole toolchain for your environment. === Making the toolchain === Below you will find some generic instructions: Change the variables in the User Configuration section of the Makefile to match your environment. They can be overridden at the command line as well. Please note, a lot of conditional instructions have been added, so it should work most of the time just out-of-the-box for your environment. Then execute the following for preparing the sources: ./download.sh ./unpack.sh Finally, input (for BSD, please use gmake instead): make Depending of your environment, this can take a bunch of hours. So please be patient! If anything goes wrong, check the output in logs/. === Making the GNU Debugger (gdb) === For the sh-elf toolchain, if you want to use the GNU Debugger (gdb), you can make it by entering: make gdb This will install gdb in the sh-elf toolchain (gdb is used with dcload/dc-tool programs, which are part of KallistiOS too). == Removing all useless files == After the toolchain compilation, you can cleanup everything by entering: ./cleanup.sh This will save a lot of space. == Final note == Please see the comments at the top of the Makefile for more build options. cf8a1cb174411d8f6bbe3e6a1c942f13ae69cdd1 798 797 2020-03-07T22:34:05Z Unknown user 0 /* Removing all useless files */ wikitext text/x-wiki In order to produces binaries targetting the Sega Dreamcast hardware, you will need 3 different toolchains: * A ''sh-elf'' toolchain, which will be the main toolchain. It targets the CPU of the Dreamcast, i.e. the Hitachi SH-4 CPU (SuperH). * An ''arm-eabi'' toolchain, which is the toolchain used only for the Yamaha Super Intelligent Sound Processor (AICA). This processor is based on an ARM7 core. It will mainly be used to compile the [[KallistiOS]] sound driver. * The host toolchain from your computer in order to produce some additional tools (i.e. the regular ''gcc'' of your computer). The ''sh-elf'' and ''arm-eabi'' toolchains may be produced by the ''dc-chain'' tool provided with KallistiOS. It's located in the ''utils'' directory. This package contains a ''Makefile'' which both simplifies building the whole Sega Dreamcast toolchain, and gives you substantial control. The dc-chain ''Makefile'' is ready to build everything you need to compile KallistiOS and then develop for the Sega Dreamcast system. == About toolchain components versions == Components that are included in a toolchain are: * '''Binutils''': mainly ld plus other tools; * '''GNU Compiler Collection''' (''gcc''); * '''Newlib''': mainly libc plus other libraries (for ''sh-elf'' only); * '''GNU Debugger''' (''gdb''): (for ''sh-elf'' only). As we are building two toolchains (sh-elf and arm-eabi), all these components will be installed twice, for both targets. Speaking about the best versions to use for the Sega Dreamcast development, they are already declared in the Makefile. This is particulary true for gcc: the best version to use at this time is the 4.7.3. We know that today this version is pretty old but greater versions have serious issues so it's better to stick with that version. Plus, gcc's bugtracker has a lot of bugs marked as [6/7/8/9 Regression] for the sh-elf target which have not been resolved. Newer isn't always better, especially with gcc targets that aren't high-priority. == Advanced options == You may attempt to spawn multiple jobs with make. Using make -j4 is recommended for speeding up the building of the toolchain. There is an option inside the Makefile to set the number of jobs for the building phases. Set the makejobs variable in the Makefile to whatever you would normally feel the need to use on the command line, and it will do the right thing. In the old times, this option may breaks things, so, if you run into trouble, you should clear this variable and try again with just one job running. On MinGW/MSYS environment, it has been confirmed that multiple jobs breaks the toolchain, so please don't try to do that under this environment. This option is disabled by default in this scenario. This doesn't apply to the others environments, including MinGW-w64/MSYS2. == Usage == Before you start, please browse the ./doc directory and check if they are full instructions for building the whole toolchain for your environment. === Making the toolchain === Below you will find some generic instructions: Change the variables in the User Configuration section of the Makefile to match your environment. They can be overridden at the command line as well. Please note, a lot of conditional instructions have been added, so it should work most of the time just out-of-the-box for your environment. Then execute the following for preparing the sources: ./download.sh ./unpack.sh Finally, input (for BSD, please use gmake instead): make Depending of your environment, this can take a bunch of hours. So please be patient! If anything goes wrong, check the output in logs/. === Making the GNU Debugger (gdb) === For the sh-elf toolchain, if you want to use the GNU Debugger (gdb), you can make it by entering: make gdb This will install gdb in the sh-elf toolchain (gdb is used with dcload/dc-tool programs, which are part of KallistiOS too). === Removing all useless files === After the toolchain compilation, you can cleanup everything by entering: ./cleanup.sh This will save a lot of space. == Final note == Please see the comments at the top of the Makefile for more build options. c30bf7fed70b401ed9c4b4d39c89e6fc612aea05 Development 0 2 800 776 2020-03-09T16:55:41Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 5733065abf0772f0e57ae1aef6cbd8169f6a4958 Docker images 0 266 801 2020-03-09T17:03:40Z Unknown user 0 Created page with "== Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for..." wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. dba8bd555e114c5f57a8db79f1fb4246e5a78b2c 802 801 2020-03-10T13:15:46Z Unknown user 0 wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [ https://hub.docker.com/repository/registry-1.docker.io/segadreamcast/toolchains/tags?page=1 dc-toolchain] - Sizious updated toolchain (gcc5.2 and gcc9) 02b7f13320542aa39d1d5442e1d3cde8717c66bb 803 802 2020-03-10T13:18:10Z Unknown user 0 wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/repository/registry-1.docker.io/segadreamcast/toolchains/tags?page=1 dc-toolchain] - Sizious updated toolchain (gcc5.2 and gcc9) 80f2ddee9dd74f1bcce7dfe38a6f6a177ceaa5cd 824 803 2020-03-10T21:36:26Z Unknown user 0 /* Community premade docker image */ wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/orgs/segadreamcast/repositories segadreamcast/toolchains] - [[User:SiZiOUS]] updated toolchain (gcc5.2 and gcc9) 15aa362fa560ac9889c3f72985f9ae06a454e019 825 824 2020-03-10T21:36:43Z Unknown user 0 /* Community premade docker image */ wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/orgs/segadreamcast/repositories segadreamcast/toolchains] - [[User:SiZiOUS SiZiOUS]] updated toolchain (gcc5.2 and gcc9) 42f52ec3659ca4ec441974f7fb4fb9e6439963d1 826 825 2020-03-10T21:37:29Z Unknown user 0 /* Community premade docker image */ wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/orgs/segadreamcast/repositories segadreamcast/toolchains] - [[User:SiZiOUS|SiZiOUS]] updated toolchain (gcc5.2 and gcc9) 82fbeebbd7f2cc1b176aa50977f132c2b510b3e0 Dreamcast.wiki 0 1 804 557 2020-03-10T14:27:33Z Unknown user 0 /* How To */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] {{DCWiki:About}} == How To == * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] * Connect to a [[Modern A/V guide|modern television or display]] * [[MIL-CD Compatibility | Identify a MIL-CD Compatible Console]] {{DCWiki:Software}} {{DCWiki:Hardware}} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 1fd659c451cc55050d43a5f538558e49dabf5333 816 804 2020-03-10T17:09:24Z Unknown user 0 /* How To */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] {{DCWiki:About}} == How To == * Identify a [[MIL-CD compatibility|MIL-CD compatible console]] to ensure your console is capable of booting CD-ROM and CD-R media * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] * Connect to a [[Modern A/V guide|modern television or display]] {{DCWiki:Software}} {{DCWiki:Hardware}} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} b4361322a02f0aa0e2e1077efdccc66d5529ed5c MIL-CD compatibility 0 267 805 2020-03-10T15:22:36Z Unknown user 0 Create page, initial info wikitext text/x-wiki A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MILCD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not exactly rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MILCD Incompatible" in white text in Japanese. "MILCD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around the front of the box (e.g. the Sakura Taisen label is on the bottom right corner.) * ''Help, images wanted'' == Limited Editions and MIL-CD Compatibility == Notes: * Yes == Compatible, No == Incompatible * Years are years of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan) North America: * Sega Sports (July/August 2000) - Yes Japan:<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MILCD compatible. == References == 3bb000c68bdefc7b03dcf8569af01e8ff567f534 806 805 2020-03-10T15:25:54Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Rearrange console order to better match release dates wikitext text/x-wiki A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MILCD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not exactly rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MILCD Incompatible" in white text in Japanese. "MILCD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around the front of the box (e.g. the Sakura Taisen label is on the bottom right corner.) * ''Help, images wanted'' == Limited Editions and MIL-CD Compatibility == Notes: * Yes == Compatible, No == Incompatible * Years are years of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan) North America: * Sega Sports (July/August 2000) - Yes Japan:<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MILCD compatible. == References == 065b2f96a323b8a9c4c8170cc927c1ffe9b4be33 807 806 2020-03-10T15:26:30Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ wikitext text/x-wiki A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MILCD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not exactly rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MILCD Incompatible" in white text in Japanese. "MILCD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around the front of the box (e.g. the Sakura Taisen label is on the bottom right corner.) * ''Help, images wanted'' == Limited Editions and MIL-CD Compatibility == Notes: * Yes == Compatible, No == Incompatible * Years are year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan) North America: * Sega Sports (July/August 2000) - Yes Japan:<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 418b12eaa09f68c08361751ba8558637472ce181 808 807 2020-03-10T15:28:52Z Unknown user 0 formatting, typos wikitext text/x-wiki A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not exactly rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MILCD Incompatible" in white text in Japanese. "MILCD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around the front of the box (e.g. the Sakura Taisen label is on the bottom right corner.) * ''Help, images wanted'' == Limited Editions and MIL-CD Compatibility == Notes: * Yes == Compatible, No == Incompatible * Years are year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan) North America: * Sega Sports (July/August 2000) - Yes Japan:<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 638d47786a8164ed7d1cf3a431d2b7f56d3f3daf 809 808 2020-03-10T15:33:14Z Unknown user 0 more typos wikitext text/x-wiki A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted'' == Limited Editions and MIL-CD Compatibility == Notes: * Yes == Compatible, No == Incompatible * Years are year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan) North America: * Sega Sports (July/August 2000) - Yes Japan:<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 9c96435b492070687906686604269b1b8d298607 810 809 2020-03-10T15:40:31Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ wikitext text/x-wiki A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually 1-3 months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 690695f72ebc434dde5c785133a2d8c39535b96a 811 810 2020-03-10T15:46:42Z Unknown user 0 clarified what help is needed for wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually 1-3 months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == ef2eee8614c5b73c26bd1b11c7c360a8bab40c96 812 811 2020-03-10T15:55:47Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually 1-3 months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 0432f27fe0dcc8bab6398388731dee47ea3641b3 813 812 2020-03-10T16:50:05Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Add divers cx-1 wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually 1-3 months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Divers CX-1 (2000) - Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 40836e58c7acc15263a9d6ad75e1bbcf7c950a87 814 813 2020-03-10T17:09:13Z Unknown user 0 Darc moved page [[MIL-CD Compatibility]] to [[MIL-CD compatibility]] wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually 1-3 months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Divers CX-1 (2000) - Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> * Super Black (2000) - Yes * R7 (2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 40836e58c7acc15263a9d6ad75e1bbcf7c950a87 817 814 2020-03-10T18:04:51Z Unknown user 0 Some R7s have a manufacturing date of 1999! https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/ <-- Same guy -->https://retrostuff.org/2017/06/11/sega-dreamcast-karaoke/ wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually 1-3 months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Divers CX-1 (2000) - Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> * Super Black (2000) - Yes * R7 (1999, 2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 2a585adb720a25952d3c3d8c710a5550f52d6801 818 817 2020-03-10T18:05:34Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Eh, it's too variable to put a number on how many months before sell time manufacturing occurs wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Divers CX-1 (2000) - Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> * Super Black (2000) - Yes * R7 (1999, 2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 078113327b471ad9d3b1b2c0ae97b32f6496b8c3 819 818 2020-03-10T18:13:10Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Divers CX-1 (2000) - Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> * Super Black (2000) - Yes * R7 (1999<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref>, 2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == 51dc4cc2d9cf66f2b644363cbfbd55ee2ef2e687 820 819 2020-03-10T18:13:39Z Unknown user 0 woops, missed a silly comma wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == '''Notes:''' * Yes == Compatible, No == Incompatible * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). * Manufacturer dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. '''North America:''' * Sega Sports (July/August 2000) - Yes '''PAL:''' * Sonic the Hedgehog 10th Anniversary (??) - Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> '''Japan:'''<ref>After searching for several hours and through thousands of listings for boxes and bottom stickers, this should be all of the Japanese ones...</ref> * RX-78 Gundam Edition (??<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref>) - No * Pearl Blue (2001) - No * Pearl Pink (2001) - No * Metallic Silver (2001) - No * Sakura Taisen (2000) - No * Divers CX-1 (2000) - Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> * Super Black (2000) - Yes * R7 (1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000) - Yes * Biohazard: Code Veronica (1999) - Yes * Biohazard S.T.A.R.S. (1999) - Yes * Red Seaman Christmas Package (1999) - Yes * Clear Seaman (1999) - Yes * Hello Kitty Pink (1999) - Yes * Hello Kitty Blue (1999) - Yes * Maziora (1999) - Yes The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. == References == b0e06ea66282ca1e57cf887d4f3941a5fa673532 821 820 2020-03-10T19:37:25Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type and region ! Date of manufacture ! Compatible? |- | Sega Sports (North America) || July/August 2000 || Yes |- | Sonic 10th Anniversary (PAL) || ??? || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition (Japan) || ???<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref> || No |- | Pearl Blue || 2001 || No |- | Pearl Pink || 2001 || No |- | Metallica Silver || 2001 || No |- | Sakura Taisen || 2000 || No |- | Divers CX-1 || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> |- | Super Black || 2000 || Yes |- | R7 || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes |- | Biohazard Code: Veronica || 1999 || Yes |- | Biohazard S.T.A.R.S. || 1999 || Yes |- | Red Seaman Christmas Package || 1999 || Yes |- | Clear Seaman Christmas Package || 1999 || Yes |- | Hello Kitty Pink || 1999 || Yes |- | Hello Kitty Blue || 1999 || Yes |- | Maziora || 1999 || Yes |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate and not every console has been tested. It may be possible, for example, that some of the individual special edition consoles with box labels warning of no MIL-CD compatibility ended up with a compatible bootROM. == References == cc611d0eb89057638695e93ff3f3d8e8b4b6bd1a 822 821 2020-03-10T20:02:40Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ The color variant is called metallic, not metallica, lol. Also clarify that the estimate is just the transition point. The other ones are not guesses. wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? |- | Sega Sports || North America || July/August 2000 || Yes |- | Sonic 10th Anniversary || PAL || ??? || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || ???<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref> || No |- | Pearl Blue || Japan || 2001 || No |- | Pearl Pink || Japan || 2001 || No |- | Metallic Silver || Japan || 2001 || No |- | Sakura Taisen || Japan || 2000 || No |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> |- | Super Black || Japan || 2000 || Yes |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes |- | Biohazard Code: Veronica || Japan || 1999 || Yes |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes |- | Red Seaman Christmas Package || Japan || 1999 || Yes |- | Clear Seaman Christmas Package || Japan || 1999 || Yes |- | Hello Kitty Pink || Japan || 1999 || Yes |- | Hello Kitty Blue || Japan || 1999 || Yes |- | Maziora || Japan || 1999 || Yes |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found here: https://segaretro.org/Dreamcast_consoles_in_Japan). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. It may be possible that some of the individual special edition consoles with box labels warning of no MIL-CD compatibility ended up with a compatible bootROM. == References == 9049d7a014881d5b6ad0fe23ec3389d99c46f2a3 823 822 2020-03-10T20:35:19Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ wikitext text/x-wiki ''Help wanted: images as noted below, missing info on RX-78, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? |- | Sega Sports || North America || July/August 2000 || Yes |- | Sonic 10th Anniversary || PAL || ??? || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || ???<ref>2001 or 2002, haven't been able to find a picture of the bottom sticker</ref> || No |- | Pearl Blue || Japan || 2001 || No |- | Pearl Pink || Japan || 2001 || No |- | Metallic Silver || Japan || 2001 || No |- | Sakura Taisen || Japan || 2000 || No |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> |- | Super Black || Japan || 2000 || Yes |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes |- | Biohazard Code: Veronica || Japan || 1999 || Yes |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes |- | Red Seaman Christmas Package || Japan || 1999 || Yes |- | Clear Seaman Christmas Package || Japan || 1999 || Yes |- | Hello Kitty Pink || Japan || 1999 || Yes |- | Hello Kitty Blue || Japan || 1999 || Yes |- | Maziora || Japan || 1999 || Yes |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. It may be possible that some of the individual special edition consoles with box labels warning of no MIL-CD compatibility ended up with a compatible bootROM. == References == b072fae9494f32794c9bed0bd0b5271f7598d52d 827 823 2020-03-14T16:15:36Z Unknown user 0 Found RX-78 serial number sticker! it's 2001 wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? |- | Sega Sports || North America || July/August 2000 || Yes |- | Sonic 10th Anniversary || PAL || ??? || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No |- | Pearl Blue || Japan || 2001 || No |- | Pearl Pink || Japan || 2001 || No |- | Metallic Silver || Japan || 2001 || No |- | Sakura Taisen || Japan || 2000 || No |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> |- | Super Black || Japan || 2000 || Yes |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes |- | Biohazard Code: Veronica || Japan || 1999 || Yes |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes |- | Red Seaman Christmas Package || Japan || 1999 || Yes |- | Clear Seaman Christmas Package || Japan || 1999 || Yes |- | Hello Kitty Pink || Japan || 1999 || Yes |- | Hello Kitty Blue || Japan || 1999 || Yes |- | Maziora || Japan || 1999 || Yes |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. It may be possible that some of the individual special edition consoles with box labels warning of no MIL-CD compatibility ended up with a compatible bootROM. == References == 7d22e9395bdbcc8beb17493de4874cdb23cd1247 MIL-CD Compatibility 0 268 815 2020-03-10T17:09:13Z Unknown user 0 Darc moved page [[MIL-CD Compatibility]] to [[MIL-CD compatibility]] wikitext text/x-wiki #REDIRECT [[MIL-CD compatibility]] 4d5c9b00cba3fa3ca1482194dff7cb2c2392d683 MIL-CD compatibility 0 267 828 827 2020-03-14T16:20:10Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ I think we should stick with what we know to be true and not speculate. wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? |- | Sega Sports || North America || July/August 2000 || Yes |- | Sonic 10th Anniversary || PAL || ??? || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No |- | Pearl Blue || Japan || 2001 || No |- | Pearl Pink || Japan || 2001 || No |- | Metallic Silver || Japan || 2001 || No |- | Sakura Taisen || Japan || 2000 || No |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> |- | Super Black || Japan || 2000 || Yes |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes |- | Biohazard Code: Veronica || Japan || 1999 || Yes |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes |- | Red Seaman Christmas Package || Japan || 1999 || Yes |- | Clear Seaman Christmas Package || Japan || 1999 || Yes |- | Hello Kitty Pink || Japan || 1999 || Yes |- | Hello Kitty Blue || Japan || 1999 || Yes |- | Maziora || Japan || 1999 || Yes |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. == References == c86564d1dcc1e2a5b72d618db7ca465897058344 829 828 2020-03-14T17:44:34Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Add preliminary number produced wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || ?? |- | Pearl Pink || Japan || 2001 || No || ?? |- | Metallic Silver || Japan || 2001 || No || ?? |- | Sakura Taisen || Japan || 2000 || No || ?? |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run) + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters.</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. == References == 39206d1d7089075f85a52362dc3626b4a09cf89c 830 829 2020-03-14T17:53:30Z Unknown user 0 Add a note for math nerds like me :P wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || ?? |- | Pearl Pink || Japan || 2001 || No || ?? |- | Metallic Silver || Japan || 2001 || No || ?? |- | Sakura Taisen || Japan || 2000 || No || ?? |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run) + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters.</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref>. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000. == References == 5f7049edb0f30f29b6761b9bc900d57e5012f720 831 830 2020-03-14T18:34:42Z Unknown user 0 wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || ?? |- | Pearl Pink || Japan || 2001 || No || ?? |- | Metallic Silver || Japan || 2001 || No || ?? |- | Sakura Taisen || Japan || 2000 || No || ?? |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run) + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == e2d88f1801b3422ffba53db07f04a540ad51d18f 832 831 2020-03-14T21:35:40Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Add D-Direct color info wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Pearl Pink || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Metallic Silver || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Sakura Taisen || Japan || 2000 || No || ?? (Seem to be abundant...?) |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run) + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == 7e74fcdad4bfa814802bbf2e9f0191bedebc9a77 833 832 2020-03-14T23:09:35Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Add 100 unit source from Sega JP press release wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Pearl Pink || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Metallic Silver || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Sakura Taisen || Japan || 2000 || No || ?? (Seem to be abundant...?) |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run)<ref>https://web.archive.org/web/20111107203243/http://sega.jp/corp/release/2000/0627/</ref> + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == cb95420045622398611383ba1460d0f5b3b8f388 837 833 2020-03-15T00:27:58Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Add signature info because... why not? wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50 (40 signed)<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Pearl Pink || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Metallic Silver || Japan || 2001 || No || 200<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Sakura Taisen || Japan || 2000 || No || ?? (Seem to be abundant...?) |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run)<ref>https://web.archive.org/web/20111107203243/http://sega.jp/corp/release/2000/0627/</ref> + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500 (200 signed)<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == 288afba546be9466856054a6ee40fb7d609ec69e 838 837 2020-03-15T00:29:49Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Apparently there was a reissue of the 3 D-Direct colors (pearl pink/blue and metallic silver) wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50 (40 signed)<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Pearl Pink || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Metallic Silver || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Sakura Taisen || Japan || 2000 || No || ?? (Seem to be abundant...?) |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run)<ref>https://web.archive.org/web/20111107203243/http://sega.jp/corp/release/2000/0627/</ref> + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999,<ref>https://retrostuff.org/2016/03/04/sega-dreamcast-repair-gdemu-psu-battery-mod/</ref> 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500 (200 signed)<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == c35b6d615d6c38414b1b4751c943e0b36203d0e5 839 838 2020-03-15T00:32:54Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Found eBay listings for 1999 R7s, so don't need this ref anymore wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! MIL-CD Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50 (40 signed)<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Pearl Pink || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Metallic Silver || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Sakura Taisen || Japan || 2000 || No || ?? (Seem to be abundant...?) |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run)<ref>https://web.archive.org/web/20111107203243/http://sega.jp/corp/release/2000/0627/</ref> + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999, 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500 (200 signed)<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == 6da3e21e0beff145aea5db6abce7db3d0192f348 840 839 2020-03-15T00:41:13Z Unknown user 0 /* Limited Editions and MIL-CD Compatibility */ Clarify where the "yes" for the PAL Sonic 10th anniversary comes from wikitext text/x-wiki ''Help wanted: images as noted below, missing manufacturing year on Sonic 10th Anniversary model, and verification of the exact month when white Dreamcasts became MIL-CD incompatible'' A MIL-CD compatible Dreamcast is required in order to be able to play homebrew software and modern indie releases, or to develop on the console directly. During the Dreamcast's life, there were 3 major revisions of its motherboard, labeled VA0, VA1, and VA2/VA2.1. All VA0 and VA1 consoles are MIL-CD compatible, but at some point during in the fall of 2000 the BIOS was changed to remove MIL-CD support from VA2s. Some VA2s manufactured in the fall of 2000 may work.<ref>Help wanted: This has been really hard to verify, and it may only be September 2000 white Dreamcast units that work, if any, as anything after coincides with the manufacture of the Sakura Taisen editions, which are not MIL-CD compatible.</ref> The vast majority of machines are MIL-CD compatible, though MIL-CD incompatible VA2s are not rare. The revision number can be easily discerned from the motherboard (it's printed right on the main system board, but requires completely disassembling the console to see), the GD-ROM connector style (minimal disassembly required), or on PAL and North American units by a little number in a circle that has either 0, 1, or 2 on the bottom sticker (no disassembly required). * ''Help, images wanted of each motherboard type (VA0, VA1, VA2), each GD-ROM type as seen when looking into the console with only the shell removed, and each sticker (NA 0, 1, 2, and PAL 0, 1, 2)'' Japanese consoles are harder to tell from the outside, but the third number in the serial number sticker is actually a year of manufacture. 8 means 1998, 9 means 1999, 0 means 2000, and 1 means 2001.<ref>https://dreamcastgaga.blogspot.com/2013/05/mil-cd-comptability.html</ref> No 2001 models are known to be MIL-CD compatible, and most of the 2000s ones are compatible. All of the 1998 and 1999 ones are compatible. It should also be noted that, on the front of the box of MIL-CD incompatible Japanese units, there is a little black rectangle on the top right, underneath "NTSC-J," that states "MIL CD Incompatible" in white text in Japanese. "MIL CD," however, is written in English letters, so it's very easy to see it assuming the box is available. It is also written on the side of the box with the serial number sticker, written in white text inside a black rectangle. Note that some limited edition consoles' boxes have the NTSC-J label moved around on the front of the box (e.g. the Sakura Taisen box's label is in the bottom right corner). * ''Help, images wanted of Japanese boxes. One that just says "NTSC-J" and one that says "NTSC-J" with the "MIL CD Incompatible" label'' == Limited Editions and MIL-CD Compatibility == {| class="wikitable" ! Console type ! Region ! Date of manufacture ! MIL-CD Compatible? ! Number Produced |- | Sega Sports || North America || July/August 2000 || Yes || ~240,000<ref>[2111 DC SPORTS BUNDLE Sep-00 SEGA OF AMERICA 3 237,357] from http://www.gamepilgrimage.com/Dreamcastussales.htm</ref> |- | Sonic 10th Anniversary || PAL || May 2000 (??) || Yes<ref>It has a 1 in the circle: https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> || 50 (40 signed)<ref>https://consolevariations.com/blog/sonic-the-hedgehog-10th-anniversary-dreamcast</ref> |- | RX-78 Gundam Edition || Japan || 2001 || No || 78<ref>Each console has a sticker on the back with the total ;)</ref> |- | Pearl Blue || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Pearl Pink || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Metallic Silver || Japan || 2001 || No || 200 (1st run) + reissued?<ref>http://www.sega-dreamcast.com/jpdc.htm</ref> |- | Sakura Taisen || Japan || 2000 || No || ?? (Seem to be abundant...?) |- | Divers CX-1 || Japan || 2000 || Yes<ref>It has a VA1, year 2000 Japanese unit inside: http://www.dc-swat.ru/forum/printthread.php?tid=2481</ref> || 200<ref>https://www.techspot.com/trivia/26-divers-2000-cx-1-dreamcast-version-sega-console/</ref><ref>https://www.youtube.com/watch?v=_kE7smFspnI</ref> or 1000<ref>http://www.thedreamcastjunkyard.co.uk/2016/01/csk-holdings-brief-history-connection.html</ref> or 5000<ref>https://dreamcastgaga.blogspot.com/2015/09/dreamcast-diver-tv-cx-1-cx-1.html</ref> (why are there 3 different numbers??) |- | Super Black || Japan || 2000 || Yes || 100 (1st run)<ref>https://web.archive.org/web/20111107203243/http://sega.jp/corp/release/2000/0627/</ref> + 1000? (2nd run)<ref>http://spinzshowroom.com/deballage-dreamcast-super-black</ref> |- | R7 || Japan || 1999, 2000 || Yes || 2000 retail + 200 "Pachinko Parlor"<ref>Contrary to information on the Internet, these did NOT come with broadband adapters. It's pretty easy to tell, too: DreamPassport 3 doesn't work with the BBA!</ref> models<ref>http://spinzshowroom.com/striptease-dreamcast-regulation-7-1st-print</ref> |- | Biohazard Code: Veronica || Japan || 1999 || Yes || 1800<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Biohazard S.T.A.R.S. || Japan || 1999 || Yes || 200<ref>https://web.archive.org/web/20070302153005/http://sega.jp/corp/release/1999/1206/</ref> |- | Red Seaman Christmas Package || Japan || 1999 || Yes || 850<ref>Page 42: https://segaretro.org/Dreamcast_consoles_in_Japan#cite_note-:File:DCUK_UK_06.pdf_p42-3</ref> |- | Clear Seaman Christmas Package || Japan || 1999 || Yes || 500<ref>https://web.archive.org/web/20070302135914/http://sega.jp/corp/release/1999/0615/</ref> |- | Hello Kitty Pink || Japan || 1999 || Yes || ?? |- | Hello Kitty Blue || Japan || 1999 || Yes || ?? |- | Maziora || Japan || 1999 || Yes || 500 (200 signed)<ref>http://spinzshowroom.com/deballage-dreamcast-maziora</ref> |} * The "special sticker" limited editions (e.g. CSK, partners, etc.) appear to all be VA1/MIL-CD compatible. * Years are the year of manufacture as printed on the console's bottom sticker, and may not coincide with release dates (release dates can be found [https://segaretro.org/Dreamcast_consoles_in_Japan here]). Manufacture dates are usually a few months before sell dates due to factors like transportation and storage time. For example, the Sega Sports models were initially sold in September 2000 despite being built up to 2 months prior. * The above compatibility chart is an educated estimate as far as when the transition occurred, as not every late 2000s console has been tested. * For anyone interested in determining console percentages, the total number of Dreamcast consoles produced is ~9.16 million. Japanese: 2.41 million, North American: 4.65 million, Europe: 1.72 million, Asia: 380,000.<ref>https://www.sega-16.com/forum/showthread.php?29320-Accurate-(probably)-Dreamcast-hardware-sales</ref> == References == 9248731a1e1e8fd6798d1cd505b697de50c66a32 Broadband adapter 0 5 834 792 2020-03-14T23:41:30Z Unknown user 0 Add a lot of new info wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black ones were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen.<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. Interestingly, by way of the broadband passport web browser, there was a method to use broadband adapters with the Dreamcast Karaoke Unit to access the DreamKara service.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == 7df1a4a2f761e6138a1d335406b99348b3c72604 835 834 2020-03-14T23:47:09Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black ones were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen.<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. Interestingly, by way of the Broadband Passport web browser, there was a method to use a broadband adapter with the Dreamcast Karaoke Unit to access the DreamKara service.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == 4158aa08d9cc2c3665cf8598fadc4d056c34ab38 836 835 2020-03-15T00:19:20Z Unknown user 0 More infos! Found a lot of stuff today! wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black ones were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white ones<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Note that all broadband adapters are the same between regions, right down to the FCC sticker on the bottom of the unit. The only difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese box also included the Broadband Passport web browser. One could therefore say that all broadband adapters are technically "North American" models. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. Interestingly, by way of the Broadband Passport web browser, there was a method to use a broadband adapter with the Dreamcast Karaoke Unit to access the DreamKara service.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == 1a6debe51232ebe8cf6983ab8671aa8f7c3db2de GDEMU 0 164 841 624 2020-03-20T03:56:26Z Unknown user 0 wikitext text/x-wiki The GDEMU a [[GD-ROM]] disk drive replacement. '''Offical link''' : https://gdemu.wordpress.com == Usage == ''This content has been copied from the official source'' GDEMU is compatbile with VA1 model Dreamcasts from all regions IMPORTANT: VA2 model is not compatible. Mating GDEMU with VA0 model mainboard is possible but will cause permanent damage to the device. See installation instructions. '''Supported image types:''' * GDI (for GD-ROMs) * CDI * CCD+IMG+SUB * MDS+MDF * ISO (as data carriers for homebrew) IMPORTANT: Recently some new dumping groups have been releasing GDIs dumped with PC CD-ROM drive using so-called “swap method”. Technically there is nothing wrong with it except for slightly different “offset” on audio tracks compared to what Dreamcast drive would produce, nothing you’d even notice. But they’ve changed the way track starting address is calculated and as a result all games that have digital audio, or data split beyond track #3, will not work properly. This is not a GDEMU issuse and there is no fix planned for this – avoid such dumps. '''Image layout:''' * Every image must be put in a separate folder * Folder names must consist of: ** 2 digits for 01 to 99 ** 3 digits up to 999 ** 4 digits up to 9999 *All file names must be in DOS 8.3 format *The main image file must be called “disc” with appropriate extension IMPORTANT: Long filenames are not supported, neither are names containing non-ASCII characters. You can, however, put a file named with the game title in each folder for better organization, even if it’s a long name – it will be ignored by GDEMU. An example of correct filenames for GDI image: -- track01.bin -- track03.bin -- disc.gdi -- track02.raw == Themes == https://www.reddit.com/r/dreamcast/comments/ehd860/gdmenu_theme_manager_custom_theme_creator_for/ == Tools == *[[GDMenu]] - A homebrew program that let you choose between all your games/program on your SD card. *[[:File:GDEMU FW COLLECTION.rar|GDEmu firmware files to version 5.15.0]] *[[:File:GDEMU SD.rar|GDEmu SD Card Maker 24-04-2018]] *[[:File:Gdibuilder12 cmd.zip|gdibuilder 1.2 cmd line Windows]] *[[:File:Gdibuilder12 win.zip|gdibuilder 1.2 GUI Windows]] *[[:File:Gditools 20150714 exe.rar|gditools 20150714 exe]] *[[:File:GDMENU Builder Mono.rar|GDMenu Builder for Linux (with Mono)]] *[[:File:Gdmenu(23-8-2014).zip|GDMenu v0.01 2014-08-23]] *[[:File:GDmenu v0.2(15-09-2014) bin only.rar|GDmenu v0.2(15-09-2014) bin only]] *[[:File:GDmenu v0.3(17-10-2014) bin only.rar|GDmenu v0.3(17-10-2014) bin only]] *[[:File:GDmenu v0.4(08-02-2015).zip|GDmenu v0.4(08-02-2015)]] *[[:File:GDmenu v0.5.1(14-06-2015) bin only.rar|GDmenu v0.5.1(14-06-2015) bin only]] *[[:File:GDmenu v0.5.2(14-07-2015).zip|GDmenu v0.5.2(14-07-2015)]] *[[:File:GDmenu v0.6(24-08-2016).zip|GDmenu v0.6(24-08-2016)]] *[[:File:RebuildGDI.rar|GDI Rebuilder]] 901dfda0a9539df792229519acbb4ece6f8932a9 DREAMNEOCD 0 134 842 404 2020-03-22T02:44:31Z Unknown user 0 wikitext text/x-wiki Dream neo cd is a based of my old port neogeo cd sdl You can find the src at https://github.com/ianmicheal/DREAMNEO-CD-1.0 ###################################################################### Dream neo cd for DreamCast V 1.0 ###################################################################### Major update this is neogeo cd emulator for dreamcast it can selfboot games and run real neogeo cd games on dreamcast It can also be used from dreamshell and a sd card with out cdda In 2004 I ported this to dreamcast the first working neogeo cd emulator for our beloved console It can play real neogeo cd games and also selfboot on the same cdi Based on fosters neogeocd/sdl https://github.com/joolswills/neocdsdl Disclaimer This program requires a system rom (bios) from the original Neogeo CD console to function. This code is copyrighted and therefore you are not entitled to a copy unless you own an original Neogeo CD console. Do not enquire where to find this file. Suffice to say that it should be called neocd.bin and should be 512kb in size. A smaller version of this bios file exists on the internet, however this will no longer work with DREAMNEO CD(v 1.0 onwards) DREAMNEO-CD-1.0 IS FREE, SOURCE CODE IS FREE. SELLING IS NOT ALLOWED. YOU CAN REUSE SOURCE CODE AND TECHNICAL KNOWLEDGE AS LONG AS IT IS NOT FOR COMMERCIAL PURPOSES. Acknowledgements (in no particular order) Beta testers deluxux Anthony817 Freak dave bjankins1 Mathieu Peponas - The GNGEO source was really useful for information and was really open about licencing files to be compatible with NeoCD/SDL. Mrneo240 Coding advice inspiration Just a fantastic coder and freind https://gitlab.com/HaydenKow/nuquake troy GPF Kos cdda sound help support debugging SDL Stephane Dallongeville - C68K (68000 CPU emulator) version 0.80 Copyright 2003-2004 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Stephane Dallongeville - CZ80 (Z80 CPU emulator) version 0.9 Copyright 2004-2005 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Moopthehedgehog Memfunctions coding advice just a great guy know's his stuff https://github.com/Moopthehedgehog Thanks to all at the simulant discord for there help freindship advice https://gitlab.com/simulant/simulant A general purpose game engine for Linux, Android and the SEGA Dreamcast! https://discordapp.com/invite/TRx94EV A place for dreamcast dev's of all types and to help with the engine https://simulant-engine.appspot.com/ Thanks to every one at dctalk forum for love and support on all my projects https://www.dreamcast-talk.com/forum/index.php quzar for being the best person to have on my team in 2004 lot's code fixes and fixed a lot of the memory functions and rendering It's now fully back from the dead again after you brought back from the dead dead thank you :) The MAME team - For an incredible emulator, a source tree full of useful information, and for sucking away more of my time than any other computer program in years 8) Sam Lantinga et al. - For the amazing libSDL cross-platform C library. (Only sound is used nothing else) DC Scene - Thanks for the help translating asm to C Black aura :) Everyone Else - Thanks for taking an interest. 685473a18372f706143fa7964ba1d6aac002fc76 843 842 2020-03-22T02:44:49Z Unknown user 0 wikitext text/x-wiki Dream neo cd is a based of my old port neogeo cd sdl You can find the src at https://github.com/ianmicheal/DREAMNEO-CD-1.0 Dream neo cd for DreamCast V 1.0 Major update this is neogeo cd emulator for dreamcast it can selfboot games and run real neogeo cd games on dreamcast It can also be used from dreamshell and a sd card with out cdda In 2004 I ported this to dreamcast the first working neogeo cd emulator for our beloved console It can play real neogeo cd games and also selfboot on the same cdi Based on fosters neogeocd/sdl https://github.com/joolswills/neocdsdl Disclaimer This program requires a system rom (bios) from the original Neogeo CD console to function. This code is copyrighted and therefore you are not entitled to a copy unless you own an original Neogeo CD console. Do not enquire where to find this file. Suffice to say that it should be called neocd.bin and should be 512kb in size. A smaller version of this bios file exists on the internet, however this will no longer work with DREAMNEO CD(v 1.0 onwards) DREAMNEO-CD-1.0 IS FREE, SOURCE CODE IS FREE. SELLING IS NOT ALLOWED. YOU CAN REUSE SOURCE CODE AND TECHNICAL KNOWLEDGE AS LONG AS IT IS NOT FOR COMMERCIAL PURPOSES. Acknowledgements (in no particular order) Beta testers deluxux Anthony817 Freak dave bjankins1 Mathieu Peponas - The GNGEO source was really useful for information and was really open about licencing files to be compatible with NeoCD/SDL. Mrneo240 Coding advice inspiration Just a fantastic coder and freind https://gitlab.com/HaydenKow/nuquake troy GPF Kos cdda sound help support debugging SDL Stephane Dallongeville - C68K (68000 CPU emulator) version 0.80 Copyright 2003-2004 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Stephane Dallongeville - CZ80 (Z80 CPU emulator) version 0.9 Copyright 2004-2005 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Moopthehedgehog Memfunctions coding advice just a great guy know's his stuff https://github.com/Moopthehedgehog Thanks to all at the simulant discord for there help freindship advice https://gitlab.com/simulant/simulant A general purpose game engine for Linux, Android and the SEGA Dreamcast! https://discordapp.com/invite/TRx94EV A place for dreamcast dev's of all types and to help with the engine https://simulant-engine.appspot.com/ Thanks to every one at dctalk forum for love and support on all my projects https://www.dreamcast-talk.com/forum/index.php quzar for being the best person to have on my team in 2004 lot's code fixes and fixed a lot of the memory functions and rendering It's now fully back from the dead again after you brought back from the dead dead thank you :) The MAME team - For an incredible emulator, a source tree full of useful information, and for sucking away more of my time than any other computer program in years 8) Sam Lantinga et al. - For the amazing libSDL cross-platform C library. (Only sound is used nothing else) DC Scene - Thanks for the help translating asm to C Black aura :) Everyone Else - Thanks for taking an interest. 6a692fe0f1f882baeb31204a97a84a895ab0ed16 844 843 2020-03-22T03:20:46Z Unknown user 0 wikitext text/x-wiki Dream neo cd is a based of my old port neogeo cd sdl You can find the src at https://github.com/ianmicheal/DREAMNEO-CD-1.0 Dream neo cd for DreamCast V 1.0 [http://Youtube Youtube]https://youtu.be/H3_0t7dvz1I Major update this is neogeo cd emulator for dreamcast it can selfboot games and run real neogeo cd games on dreamcast It can also be used from dreamshell and a sd card with out cdda In 2004 I ported this to dreamcast the first working neogeo cd emulator for our beloved console It can play real neogeo cd games and also selfboot on the same cdi Based on fosters neogeocd/sdl https://github.com/joolswills/neocdsdl Disclaimer This program requires a system rom (bios) from the original Neogeo CD console to function. This code is copyrighted and therefore you are not entitled to a copy unless you own an original Neogeo CD console. Do not enquire where to find this file. Suffice to say that it should be called neocd.bin and should be 512kb in size. A smaller version of this bios file exists on the internet, however this will no longer work with DREAMNEO CD(v 1.0 onwards) DREAMNEO-CD-1.0 IS FREE, SOURCE CODE IS FREE. SELLING IS NOT ALLOWED. YOU CAN REUSE SOURCE CODE AND TECHNICAL KNOWLEDGE AS LONG AS IT IS NOT FOR COMMERCIAL PURPOSES. Acknowledgements (in no particular order) Beta testers deluxux Anthony817 Freak dave bjankins1 Mathieu Peponas - The GNGEO source was really useful for information and was really open about licencing files to be compatible with NeoCD/SDL. Mrneo240 Coding advice inspiration Just a fantastic coder and freind https://gitlab.com/HaydenKow/nuquake troy GPF Kos cdda sound help support debugging SDL Stephane Dallongeville - C68K (68000 CPU emulator) version 0.80 Copyright 2003-2004 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Stephane Dallongeville - CZ80 (Z80 CPU emulator) version 0.9 Copyright 2004-2005 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Moopthehedgehog Memfunctions coding advice just a great guy know's his stuff https://github.com/Moopthehedgehog Thanks to all at the simulant discord for there help freindship advice https://gitlab.com/simulant/simulant A general purpose game engine for Linux, Android and the SEGA Dreamcast! https://discordapp.com/invite/TRx94EV A place for dreamcast dev's of all types and to help with the engine https://simulant-engine.appspot.com/ Thanks to every one at dctalk forum for love and support on all my projects https://www.dreamcast-talk.com/forum/index.php quzar for being the best person to have on my team in 2004 lot's code fixes and fixed a lot of the memory functions and rendering It's now fully back from the dead again after you brought back from the dead dead thank you :) The MAME team - For an incredible emulator, a source tree full of useful information, and for sucking away more of my time than any other computer program in years 8) Sam Lantinga et al. - For the amazing libSDL cross-platform C library. (Only sound is used nothing else) DC Scene - Thanks for the help translating asm to C Black aura :) Everyone Else - Thanks for taking an interest. 61e717681b8dde2151ed60b740fa561747288afb DCWiki:Software 4 81 845 689 2020-03-23T23:33:36Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * [[Online Services]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[VMU development]] * [[Useful programming tips]] |} |} 7c7873e5f3b2cf26fbebadce20747cac112abe11 Useful programming tips 0 269 846 2020-03-24T00:18:27Z Unknown user 0 ugh, this is gonna need some work and I don't have time right now wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. === Alignment === The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: <code> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </code> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do this to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero extend, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! === Cache Management === == References == 3f0dbfea08bb77d3640c2904052d9cd92a274b77 Development 0 2 847 800 2020-03-24T21:41:41Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] f25c46cc188a1a490ff040301d032e0972f03ae9 872 847 2020-05-07T12:07:28Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 0c3a45198f6377dd1f9e5e76029839f32c9e646e Flash Memory Eraser 0 163 850 514 2020-03-31T02:26:46Z Unknown user 0 wikitext text/x-wiki The '''Dreamcast Flash Memory Eraser''' is a small utility that erases the entire writable flash ROM of the Dreamcast. This is most useful for changing the serial number and access key for [[Phantasy Star Online]]. When run, it will show the Sega copyright screen and display a red border; when the red border turns green, the flash ROM is erased. Note that this disc will delete all settings and information from the Dreamcast's internal memory, so you will lose PSO serial number/access key information, ISP settings, etc. Warning: A user that has connected a +12V wire mod to enable writing to the normally read-only flash partition to [[region change|change the Dreamcast's region coding or swirl color]] and left that wire connected will brick their console by running this disc. The console will be a no-region console unable to boot any discs unless the console is modded with a region-free BIOS. [[:File:DCFlash.zip|Download CDI image]] 38b652ef98fb29ba52e87448b1c1ea055ee7955d File:DCFlash.zip 6 162 851 511 2020-03-31T03:33:16Z Unknown user 0 /* Summary */ wikitext text/x-wiki == Summary == see [[Flash Memory Eraser]] for more information 5385ef3c8fa5c7730feef9c56e402a41e5ed0279 Docker images 0 266 854 826 2020-04-08T18:45:48Z Unknown user 0 wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/orgs/segadreamcast/repositories segadreamcast/toolchains] - [[User:SiZiOUS|SiZiOUS]] updated toolchain (gcc5.2 and gcc9) * [https://github.com/einsteinx2/docker-dcdev] - Einsteinx2 updated (gcc 9.3) toolchain f4ff49d00423b35ade47ff6b5854bc802960b15c 855 854 2020-04-08T18:46:04Z Unknown user 0 wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/orgs/segadreamcast/repositories segadreamcast/toolchains] - [[User:SiZiOUS|SiZiOUS]] updated toolchain (gcc5.2 and gcc9) * [https://github.com/einsteinx2/docker-dcdev einsteinx2 toolchain] - Einsteinx2 updated (gcc 9.3) toolchain 88372826b8f5581103143c17eb80b3be90f822b4 857 855 2020-04-15T20:51:54Z Unknown user 0 /* Community premade docker image */ wikitext text/x-wiki == Community premade docker image == * [https://github.com/mrneo240/nu-dc_kos nu-dc_kos] - Contains the toolchaine + kos + some extra dev tools. Check the github's readme for usage. * [https://github.com/mrneo240/nu-dcdev nu-dcdev] - Contains the toolchain + kos. Check the github's readme for usage. * [https://hub.docker.com/orgs/segadreamcast/repositories segadreamcast/toolchains] - [[User:SiZiOUS|SiZiOUS]] updated toolchain (gcc5.2 and gcc9) * [https://github.com/einsteinx2/docker-dcdev einsteinx2 toolchain] - [[User:Einsteinx2|einsteinx2]] updated (GCC 9.3 and GCC 4.7.4) toolchains bfa412c0d53511c13f785f2193f5d75b92339c8d Talk:Development 1 273 856 2020-04-08T18:50:26Z Unknown user 0 Created page with "dumping size of symbols from an elf with scary oneliners <pre> Common Symbols: awk '/Allocating common symbols/ {print "Start: "FNR}' output.map && awk '/Memory Configuration..." wikitext text/x-wiki dumping size of symbols from an elf with scary oneliners <pre> Common Symbols: awk '/Allocating common symbols/ {print "Start: "FNR}' output.map && awk '/Memory Configuration/ {print "End: "FNR}' output.map gawk --non-decimal-data '{ $1 = sprintf("%d\t"$1, $2) } (FNR>412 && FNR<1093)' output.map | sort -n OR echo 'gawk --non-decimal-data '"'"'{ $1 = sprintf("%d\t"$1, $2) } (FNR>'`awk '/Allocating common symbols/ {print FNR}' output.map`' && FNR<'`awk '/Memory Configuration/ {print FNR}' output.map`')'"'"' output.map | sort -n' | sh BSS area: awk '/ \*\(\.bss\)/ {print "Start: "FNR}' output.map && awk '/ \*\(\.bss\.\*\)/ {print "End: "FNR}' output.map gawk --non-decimal-data '{ $1 = sprintf("%d\t"$1, $3) } (FNR>4642 && FNR<4720)' output.map | sort -n OR echo 'gawk --non-decimal-data '"'"'{ $1 = sprintf("%d\t"$1, $3) } (FNR>'`awk '/ \*\(\.bss\)/ {print FNR}' output.map`' && FNR<'`awk '/ \*\(\.bss\.\*\)/ {print FNR}' output.map`')'"'"' output.map | sort -n' | sh RODATA: awk '/ \*\(\.rodata\)/ {print "Start: "FNR}' output.map && awk '/ \*\(\.rodata\.\*\)/ {print "End: "FNR}' output.map gawk --non-decimal-data '{ $1 = sprintf("%d\t"$1, $3) } (FNR>3892 && FNR<4112)' output.map | sort -n OR echo 'gawk --non-decimal-data '"'"'{ $1 = sprintf("%d\t"$1, $3) } (FNR>'`awk '/ \*\(\.rodata\)/ {print FNR}' output.map`' && FNR<'`awk '/ \*\(\.rodata\.\*\)/ {print FNR}' output.map`')'"'"' output.map | sort -n' | sh </pre> --[[User:Neo|Neo]] ([[User talk:Neo|talk]]) 13:50, 8 April 2020 (CDT) 5e942ba03e15c942a1e8397e99f29ed91faf8e68 Optical drive replacements 0 16 858 525 2020-04-17T17:37:13Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Examples include: * [[GDEMU]] (official version and clones) * USB-GDROM * iceGDROM (DIY, not a product) * MODE - Multi Optical Drive Emulator [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html Unreleased, preorder here] 380acf89b8a0e912674c4a9935727ec71032099d 859 858 2020-04-17T22:07:06Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Examples include: * [[GDEMU]] (official version and clones) * USB-GDROM * iceGDROM (DIY, not a product) * MODE - Multi Optical Drive Emulator [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html Unreleased, preorder here] {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#b6b6b6;" width="300" | Device: | width="400" | GDEMU | width="400" | USB-GDROM | width="400" | MODE | width="400" | iceGDROM |- |console revisions supported || va1 only || va0 and va1 || ??? (no va2 support) || ??? (no va2 support) |- |media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0<br>SATA through built-in USB 2.0 bridge || SD cards |- |media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || ??? || ??? |- |menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || ?? || FAT32, requires conversion to custom image format, files must be specifically numbered |- |image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |bleemcast! GT2/TK3/MGS version support | style="background-color:#ff9995;" | no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | style="background-color:#ff9995;" | no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? | style="background-color:#ff9995;" | no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |availability || periodic sales done on creator's website, shipped from Poland<br>unofficial China-based clones widely available worldwide || sale's through creator's website, shipped from Russia || currently unreleased, ETA |} 9d42309cea1aea6d1b6550ee4630f23e445ae93e 860 859 2020-04-17T22:39:59Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 to purchase as a Paypal gift<br>$220 to purchase with Paypal protection<br>additional $15 for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html Unreleased, preorder here], ETA || DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || ??? || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || ??? || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support in menu<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical)<br>Freezing during Skies of Arcadia intro menu (non-critical)<br>D2 disc swapping bug || ??? || ??? || ??? |} fb798c5d1408a81b1b211aa45b4c87487d00e370 861 860 2020-04-17T22:50:47Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support in menu<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical)<br>Freezing during Skies of Arcadia intro menu (non-critical)<br>D2 disc swapping bug || ??? || ??? || ??? |} 38309688634d6573f688084678276944b9bc1414 862 861 2020-04-17T23:06:26Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support in menu<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, have to power cycle console with power button || ??? || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug)<br>Freezing during Skies of Arcadia intro video (non-critical)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>All clones contain latest firmware || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} eeb61fe876666ac97db4aadd4b7f2dcbee0111a9 863 862 2020-04-17T23:21:46Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtual perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support in menu<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, have to power cycle console with power button || ??? || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug)<br>Freezing during Skies of Arcadia intro video (non-critical)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>All clones contain latest firmware || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} 819b6fac953afbbf8ccf6e4bda88e86e7bd7ce83 864 863 2020-04-17T23:22:04Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support in menu<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, have to power cycle console with power button || ??? || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug)<br>Freezing during Skies of Arcadia intro video (non-critical)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>All clones contain latest firmware || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} e59b8b76377ba4260a5288284b9972d1e79161a4 Check-GD 0 257 865 755 2020-04-21T00:07:47Z Unknown user 0 wikitext text/x-wiki There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant versions of the software intended for different use cases. =Known pressed & labelled GD-ROMs= *'''SDPS-1''': Loop Checker / 1.00 / SEGA CS / 01/06/2000 ('''dumped''') *'''SDPS-2''': Unknown ('''undumped''') *'''SDPS-3''': DC checker for REPAIR / 2.15R / CS.R&D / 01/12/2000 ('''undumped''') *'''SDPS-4''': DC checker for MP / 2.16M / CS / 02/02/2000 ('''dumped''') *'''SDPS-5''': DC checker for REPAIR / 2.16R / CS / 02/02/2000 ('''undumped''') *'''SDPS-6''': Unknown ('''undumped''') *'''SDPS-7''': Himozuke Family / 2.40 / CS / 07/14/2000 ('''undumped''') *Internal Printing Disc (HKT-999999) - ('''undumped''') No images available, believed to be the same software as GD Drive Repair Program silver disc? *DC Checker for Repair v2.05R (DCSC205R) ('''dumped''') (10/27/1999 date in IP.BIN) *GD Drive Repair Program 0.1 (DCGD01) ('''dumped''') (12/01/1998 date in IP.BIN) ==Hidden options== There are multiple modes that the disc can be run in depending on what buttons you hold down at the IP.BIN screen: *Holding nothing: Full checker *Holding A + B: Full checker but without modem checks, req. for Asian modemless consoles to pass *Holding X + Down on D-Pad: MP Checker mode, skips critical tests but runs the other tests *Holding X + Right on D-Pad: Single test mode, disables test script and allows you to scroll through the individual tests and pick them at will *Holding Y + Up on D-Pad: CLX Signature check, which renders a scene and compares calculated graphics data against reference data *Holding Y + Right: CLX Signature Aging test, which performs the above test repeatedly on a loop. This test is available with and without a GD drive seek test included in the test loop. *Holding Y + Down on D-Pad: Sonic Cube mode, which allows you to run several Holly samples, basically the same ones that are run during the scripted test modes, but you can control them with controller. **Non-Tex Cube **Tex Cube **Punch-Thru Cube (X+Up/Down increases/decreases number of cubes, Y+Up/Down zooms in and out, start pauses/resumes motion) **Vertex Test (B toggles mirror map and transparency, d-pad moves screen) **Torus test (A changes number of doughnuts, Y+Up/Down zooms in/out, start pauses/resumes motion) *Holding X + Left: FlashROM viewer mode, which displays information about the console stored in the FlashROM (serial number, factory codes, etc.) *Holding X + Up: Katana Set5 checker mode, which runs the same diagnostic tests as those built into the BIOS of the Katana Set5 *Holding A + B + X + Down: Address checker mode, which displays a blank screen but allows the user to control a "tiny address checker" program via serial link ==Console bricking risk== During the test process, the console flashROM is subject to both read and write tests, which result in the flashROM being completely erased (along with all console settings, ISP settings, [[Phantasy Star Online]] serial number & access code, etc.). This will not cause issues on a stock console, however, if the console has been modified with the [[region change]] mod and the write-enable wire has not been removed, the console's region coding will be erased and the console will no longer boot any software unless the flashROM is repaired or a region-free BIOS is installed. ab3608a896da33b57cf4cadeb21c5106d5587ba9 866 865 2020-04-21T00:08:38Z Unknown user 0 wikitext text/x-wiki There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant versions of the software intended for different use cases. =Known pressed & labelled GD-ROMs= *'''SDPS-1''': Loop Checker / 1.00 / SEGA CS / 01/06/2000 ('''dumped''') *'''SDPS-2''': Unknown ('''undumped''') *'''SDPS-3''': DC checker for REPAIR / 2.15R / CS.R&D / 01/12/2000 ('''undumped''') *'''SDPS-4''': DC checker for MP / 2.16M / CS / 02/02/2000 ('''dumped''') *'''SDPS-5''': DC checker for REPAIR / 2.16R / CS / 02/02/2000 ('''undumped''') *'''SDPS-6''': Unknown ('''undumped''') *'''SDPS-7''': Himozuke Family / 2.40 / CS / 07/14/2000 ('''undumped''') *Internal Printing Disc (HKT-999999) - ('''undumped''') No images available, believed to be the same software as GD Drive Repair Program silver disc? =Known pressed silvers= *DC Checker for Repair v2.05R (DCSC205R) ('''dumped''') (10/27/1999 date in IP.BIN) *GD Drive Repair Program 0.1 (DCGD01) ('''dumped''') (12/01/1998 date in IP.BIN) ==Hidden options== There are multiple modes that the disc can be run in depending on what buttons you hold down at the IP.BIN screen: *Holding nothing: Full checker *Holding A + B: Full checker but without modem checks, req. for Asian modemless consoles to pass *Holding X + Down on D-Pad: MP Checker mode, skips critical tests but runs the other tests *Holding X + Right on D-Pad: Single test mode, disables test script and allows you to scroll through the individual tests and pick them at will *Holding Y + Up on D-Pad: CLX Signature check, which renders a scene and compares calculated graphics data against reference data *Holding Y + Right: CLX Signature Aging test, which performs the above test repeatedly on a loop. This test is available with and without a GD drive seek test included in the test loop. *Holding Y + Down on D-Pad: Sonic Cube mode, which allows you to run several Holly samples, basically the same ones that are run during the scripted test modes, but you can control them with controller. **Non-Tex Cube **Tex Cube **Punch-Thru Cube (X+Up/Down increases/decreases number of cubes, Y+Up/Down zooms in and out, start pauses/resumes motion) **Vertex Test (B toggles mirror map and transparency, d-pad moves screen) **Torus test (A changes number of doughnuts, Y+Up/Down zooms in/out, start pauses/resumes motion) *Holding X + Left: FlashROM viewer mode, which displays information about the console stored in the FlashROM (serial number, factory codes, etc.) *Holding X + Up: Katana Set5 checker mode, which runs the same diagnostic tests as those built into the BIOS of the Katana Set5 *Holding A + B + X + Down: Address checker mode, which displays a blank screen but allows the user to control a "tiny address checker" program via serial link ==Console bricking risk== During the test process, the console flashROM is subject to both read and write tests, which result in the flashROM being completely erased (along with all console settings, ISP settings, [[Phantasy Star Online]] serial number & access code, etc.). This will not cause issues on a stock console, however, if the console has been modified with the [[region change]] mod and the write-enable wire has not been removed, the console's region coding will be erased and the console will no longer boot any software unless the flashROM is repaired or a region-free BIOS is installed. 2d3f23511483d1fb2a424647d8e8909439a542e6 Battery replacement 0 96 867 721 2020-04-28T05:57:41Z Unknown user 0 It's an ML 2430, not 2450. No wonder I couldn't find a datasheet, lol wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of the ML2032 in the future. It is recommended '''not''' to use the LIR2032 battery type as the Dreamcast does not output the voltage necessary for it to properly and fully recharge. Specifically, the ML2032 (and ML2020 and ML2430) are 3V batteries,<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref><ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref><ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> while the LIR2032 type is generally 3.6V or 3.7V.<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> == Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == fdd9a9425f9d3793b2dcfb8fdfa42e57a499c3f8 DreamPi PF Configuration Example 0 274 868 2020-04-29T04:47:12Z Unknown user 0 Created page with "This is an example of how I set up an OpenBSD router to work with all games on DreamPi. These settings should be similar to what's necessary for a PFSense or FreeBSD based rou..." wikitext text/x-wiki This is an example of how I set up an OpenBSD router to work with all games on DreamPi. These settings should be similar to what's necessary for a PFSense or FreeBSD based router. *On your DreamPi, put an empty file named /boot/ssh on the card and boot the DreamPi in order to enable ssh. *SSH into the DreamPi using username: pi and password: raspberry, and make sure to change the password using "sudo passwd pi" *On your Raspberry Pi, stop the DreamPi service with "sudo service dreampi stop" *Use nano to edit the dreampi.py configuration: "sudo nano /home/pi/dreampi/dreampi.py" *Find these lines: <pre>this_ip = find_next_unused_ip(".".join(subnet) + ".100") dreamcast_ip = find_next_unused_ip(this_ip)</pre> *Replace with: <pre>#this_ip = find_next_unused_ip(".".join(subnet) + ".100") #dreamcast_ip = find_next_unused_ip(this_ip) this_ip = "192.168.1.19" dreamcast_ip = "192.168.1.20"</pre> In this example, 192.168.1.19 is the IP address you want to use for your DreamPi modem's IP address, and 192.168.1.20 is the IP address you want to use for your Dreamcast. Make sure you pick an IP not within your DHCP pool. *Save the file. *Start the DreamPi service with "sudo service dreampi start" *The DreamPi will now always use the same IP address, so it will now be easier to configure your PF firewall. *Here are the following relevant entries from my /etc/pf.conf: <pre>#define dreamcast/dreampi ipv4 address dreamcast = 192.168.1.20 # dreampi at 192.168.1.19 # dreamcast ports to forward # AFO: UDP 7980 # ChuChuRocket: UDP 9789 # IGP: UDP 5656, TCP 5011, TCP 10500, TCP 10501-10503 # 2K: UDP 5502, UDP 5503, UDP 5656, TCP 5011, TCP 6666 # NextTetris: TCP/UDP 3512 # OoogaBooga: UDP 6001 # PBA2001: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624, UDP 13139 # Planet Ring: UDP 7648, UDP 1285, UDP 1028 # Starlancer: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624 # WSB 2K2: UDP 37171, UDP 13713 # Worms World Party: TCP 17219 dreamcast_udp_ports = "{ 1028, 1285, 2300:2400, 3512, 5502:5503, 5656, 6001, 6500, 7648, 7980, 9789, 13139, 13713, 37171, 47624 }" dreamcast_tcp_ports = "{ 2300:2400, 3512, 5011, 6666, 10500:10503, 17219, 47624 }" #ext_if is the name of the external interface, e.g. ext_if = "re0" match out on $ext_if inet from $dreamcast nat-to ($ext_if) static-port pass in on $ext_if inet proto udp from any to any port $dreamcast_udp_ports rdr-to $dreamcast pass in on $ext_if inet proto tcp from any to any port $dreamcast_tcp_ports rdr-to $dreamcast</pre> *Restart pf entirely with "pfctl -F all -f /etc/pf.conf" on your BSD machine. *Your DreamPi should now be able to connect to all of the online games currently available. When new games become available in the future, you may need to update your pf.conf rules to allow these new games through. c0d84a362126112e43666101f3e01d06a6f3a5b0 870 868 2020-04-29T04:51:01Z Unknown user 0 wikitext text/x-wiki This is an example of how I set up an OpenBSD router to work with all games on DreamPi. These settings should be similar to what's necessary for a pfSense or FreeBSD based router. *On your DreamPi, put an empty file named /boot/ssh on the card and boot the DreamPi in order to enable ssh. *SSH into the DreamPi using username: pi and password: raspberry, and make sure to change the password using "sudo passwd pi" *On your Raspberry Pi, stop the DreamPi service with "sudo service dreampi stop" *Use nano to edit the dreampi.py configuration: "sudo nano /home/pi/dreampi/dreampi.py" *Find these lines: <pre>this_ip = find_next_unused_ip(".".join(subnet) + ".100") dreamcast_ip = find_next_unused_ip(this_ip)</pre> *Replace with: <pre>#this_ip = find_next_unused_ip(".".join(subnet) + ".100") #dreamcast_ip = find_next_unused_ip(this_ip) this_ip = "192.168.1.19" dreamcast_ip = "192.168.1.20"</pre> In this example, 192.168.1.19 is the IP address you want to use for your DreamPi modem's IP address, and 192.168.1.20 is the IP address you want to use for your Dreamcast. Make sure you pick an IP not within your DHCP pool. *Save the file. *Start the DreamPi service with "sudo service dreampi start" *The DreamPi will now always use the same IP address, so it will now be easier to configure your PF firewall. *Here are the following relevant entries from my /etc/pf.conf: <pre>#define dreamcast/dreampi ipv4 address dreamcast = 192.168.1.20 # dreampi at 192.168.1.19 # dreamcast ports to forward # AFO: UDP 7980 # ChuChuRocket: UDP 9789 # IGP: UDP 5656, TCP 5011, TCP 10500, TCP 10501-10503 # 2K: UDP 5502, UDP 5503, UDP 5656, TCP 5011, TCP 6666 # NextTetris: TCP/UDP 3512 # OoogaBooga: UDP 6001 # PBA2001: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624, UDP 13139 # Planet Ring: UDP 7648, UDP 1285, UDP 1028 # Starlancer: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624 # WSB 2K2: UDP 37171, UDP 13713 # Worms World Party: TCP 17219 dreamcast_udp_ports = "{ 1028, 1285, 2300:2400, 3512, 5502:5503, 5656, 6001, 6500, 7648, 7980, 9789, 13139, 13713, 37171, 47624 }" dreamcast_tcp_ports = "{ 2300:2400, 3512, 5011, 6666, 10500:10503, 17219, 47624 }" #ext_if is the name of the external interface, e.g. ext_if = "re0" match out on $ext_if inet from $dreamcast nat-to ($ext_if) static-port pass in on $ext_if inet proto udp from any to any port $dreamcast_udp_ports rdr-to $dreamcast pass in on $ext_if inet proto tcp from any to any port $dreamcast_tcp_ports rdr-to $dreamcast</pre> *Restart pf entirely with "pfctl -F all -f /etc/pf.conf" on your BSD machine. *Your DreamPi should now be able to connect to all of the online games currently available. When new games become available in the future, you may need to update your pf.conf rules to allow these new games through. 14fdc41d39f6f53e6bdcc2484cda5abb96d25077 871 870 2020-04-29T19:37:06Z Unknown user 0 wikitext text/x-wiki This is an example of how I set up an OpenBSD router to work with all games on DreamPi. These settings should be similar to what's necessary for a pfSense or FreeBSD based router. *On your DreamPi, put an empty file named /boot/ssh on the card and boot the DreamPi in order to enable ssh. *SSH into the DreamPi using username: pi and password: raspberry, and make sure to change the password using "sudo passwd pi" *On your Raspberry Pi, stop the DreamPi service with "sudo service dreampi stop" *Use nano to edit the dreampi.py configuration: "sudo nano /home/pi/dreampi/dreampi.py" *Find these lines: <pre>this_ip = find_next_unused_ip(".".join(subnet) + ".100") dreamcast_ip = find_next_unused_ip(this_ip)</pre> *Replace with: <pre>#this_ip = find_next_unused_ip(".".join(subnet) + ".100") #dreamcast_ip = find_next_unused_ip(this_ip) this_ip = "192.168.1.19" dreamcast_ip = "192.168.1.20"</pre> In this example, 192.168.1.19 is the IP address you want to use for your DreamPi modem's IP address, and 192.168.1.20 is the IP address you want to use for your Dreamcast. Make sure you pick an IP not within your DHCP pool. *Save the file. *Start the DreamPi service with "sudo service dreampi start" *The DreamPi will now always use the same IP address, so it will now be easier to configure your PF firewall. *Here are the following relevant entries from my /etc/pf.conf: <pre>#define dreamcast/dreampi ipv4 address dreamcast = 192.168.1.20 # dreampi at 192.168.1.19 # dreamcast ports to forward # AFO: UDP 7980 # ChuChuRocket: UDP 9789 # IGP: UDP 5656, TCP 5011, TCP 10500, TCP 10501-10503 # 2K: UDP 5502, UDP 5503, UDP 5656, TCP 5011, TCP 6666 # NextTetris: TCP/UDP 3512 # OogaBooga: UDP 6001 # PBA2001: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624, UDP 13139 # Planet Ring: UDP 7648, UDP 1285, UDP 1028 # Starlancer: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624 # WSB 2K2: UDP 37171, UDP 13713 # Worms World Party: TCP 17219 dreamcast_udp_ports = "{ 1028, 1285, 2300:2400, 3512, 5502:5503, 5656, 6001, 6500, 7648, 7980, 9789, 13139, 13713, 37171, 47624 }" dreamcast_tcp_ports = "{ 2300:2400, 3512, 5011, 6666, 10500:10503, 17219, 47624 }" #ext_if is the name of the external interface, e.g. ext_if = "re0" match out on $ext_if inet from $dreamcast nat-to ($ext_if) static-port pass in on $ext_if inet proto udp from any to any port $dreamcast_udp_ports rdr-to $dreamcast pass in on $ext_if inet proto tcp from any to any port $dreamcast_tcp_ports rdr-to $dreamcast</pre> *Restart pf entirely with "pfctl -F all -f /etc/pf.conf" on your BSD machine. *Your DreamPi should now be able to connect to all of the online games currently available. When new games become available in the future, you may need to update your pf.conf rules to allow these new games through. a9d11df449f1766c96e48eb3f888d87f93a3c168 DreamPi 0 18 869 535 2020-04-29T04:50:32Z Unknown user 0 wikitext text/x-wiki == Description == DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. == Material == To build a DreamPi, you need the following hardware: * A Raspberry Pi * An SD card containing the DreamPi software image * A Linux-compatible, USB dial-up voice modem (UK | US | DE) * A telephone cable * An ethernet cable * Dreamcast browser software (e.g. Dreamkey 3.0) == Voltage Line Inducer == Chances are (regardless of region) you will also need to build a line voltage inducer. This is a simple circuit which sends an electric current down the telephone cable. For this you will need: * A 0.47uf capacitor * A 380 Ohm resistor * A 9v battery connector (two if you have a PAL modem) * A 9v battery (two if you have a PAL modem) * A soldering iron, some solder, wire strippers, electrical tape, and patience == How to setup the DreamPi == Connect the Raspberry Pi to the USB modem, connect that to the phone cable, connect the phone cable to the Dreamcast. Then, connect the Raspberry Pi into your router. Now, download the image, decompress with 7zip (or whatever) and follow the instructions here to flash the image to the SD card: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md Now, insert the SD card into the Pi, and switch it on! == Configuring DreamKey or PlanetWeb == For PlanetWeb, follow the instructions found here under "Configuring the Dreamcast". For DreamKey 3.0. You need to set the ISP number to dial to 555. So, what's the deal with PAL modems? Right, it took me ages to figure this out. U.S modems come in two forms, model "A" modems, and model "B" modems. Model A modems don't draw their power from the telephone line itself, or at least, they don't require it (some USB modems do however!). Model B modems do, and so to do a direct modem-to-modem connection with one of those you need to somehow add power to the connecting phone wire. That's what a "Line Voltage Inducer" does. The best instructions I've found for this are here. But, it gets even more complicated. Generally PAL modems are classed as Model B modems - they require a line voltage. However, I found that not many PAL users had had much luck getting connected, and when I tried, it didn't work for me either, even with a line voltage inducer! Apparently it seems that U.S. Model B modems can suffice with only 9 volts added to the telephone line, but in europe our fussy PAL modems require 18 volts! This is simple enough to do, just build the line voltage inducer as normal, but chain two 9 volt batteries together in series, rather than using just one. == Video instruction == <youtube>VgRLnj2YR3s</youtube> == Firewall Configuration == It may be necessary to configure your firewall to allow games to properly connect through the DreamPi. [[DreamPi PF Configuration Example|Here]] is an example configuration for advanced users running BSD-based routers (e.g. OpenBSD, FreeBSD, pfSense, etc.) at home. == Pre made kits == [https://www.dreamcastlive.net/shop Dreamcast Live] is selling assembled DreamPi and Voltage Line Inducers. {{DCWiki:Stub}} 5ebe2c60a77d6d9bd632aea85405f7a3f8b370b8 875 869 2020-05-08T17:14:25Z Unknown user 0 wikitext text/x-wiki == Description == DreamPi is a community-designed and maintained project that allows one to use the Dreamcast's modem on a modern home network by employing a Raspberry Pi and USB modem. Using DreamPi can be preferred to a [[Broadband adapter]] in many cases because the Broadband adapter, while a much faster, is not supported in a majority of commercial online games. The Broadband adapter is also a scarce peripheral that can cost over $100USD. == Material == To build a DreamPi, you need the following hardware: * A Raspberry Pi * An SD card containing the DreamPi software image * A Linux-compatible, USB dial-up voice modem (UK | US | DE) * A telephone cable * An ethernet cable * Dreamcast browser software (e.g. Dreamkey 3.0) == Voltage Line Inducer == Chances are (regardless of region) you will also need to build a line voltage inducer. This is a simple circuit which sends an electric current down the telephone cable. For this you will need: * A 0.47uf capacitor * A 380 Ohm resistor * A 9v battery connector (two if you have a PAL modem) * A 9v battery (two if you have a PAL modem) * A soldering iron, some solder, wire strippers, electrical tape, and patience == How to setup the DreamPi == Connect the Raspberry Pi to the USB modem, connect that to the phone cable, connect the phone cable to the Dreamcast. Then, connect the Raspberry Pi into your router. Now, download the image, decompress with 7zip (or whatever) and follow the instructions here to flash the image to the SD card: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md Now, insert the SD card into the Pi, and switch it on! == Configuring DreamKey or PlanetWeb == For PlanetWeb, follow the instructions found here under "Configuring the Dreamcast". For DreamKey 3.0. You need to set the ISP number to dial to 555. So, what's the deal with PAL modems? Right, it took me ages to figure this out. U.S modems come in two forms, model "A" modems, and model "B" modems. Model A modems don't draw their power from the telephone line itself, or at least, they don't require it (some USB modems do however!). Model B modems do, and so to do a direct modem-to-modem connection with one of those you need to somehow add power to the connecting phone wire. That's what a "Line Voltage Inducer" does. The best instructions I've found for this are here. But, it gets even more complicated. Generally PAL modems are classed as Model B modems - they require a line voltage. However, I found that not many PAL users had had much luck getting connected, and when I tried, it didn't work for me either, even with a line voltage inducer! Apparently it seems that U.S. Model B modems can suffice with only 9 volts added to the telephone line, but in europe our fussy PAL modems require 18 volts! This is simple enough to do, just build the line voltage inducer as normal, but chain two 9 volt batteries together in series, rather than using just one. == Video instruction == <youtube>VgRLnj2YR3s</youtube> == Firewall Configuration == It may be necessary to configure your firewall to allow games to properly connect through the DreamPi. [[DreamPi PF Configuration Example|Here]] is an example configuration for advanced users running BSD-based routers (e.g. OpenBSD, FreeBSD, pfSense, etc.) at home. == Pre made kits == [https://www.dreamcastlive.net/shop Dreamcast Live] is selling assembled DreamPi and Voltage Line Inducers. == Internalized DreamPi == It is possible with some creativity to create a completely [[internalized DreamPi adapter]]. {{DCWiki:Stub}} c56c88fadfc40b80169fb3eae92ea30f09b0f5e7 Notes on fillrate and drawing large textures 0 275 873 2020-05-07T12:32:55Z Unknown user 0 Created page with "Those notes are from working on Reaperi Cycle and Summoning Signals, two projects that use primairly large textures for it's visual. Those projects are build using [[GLdc]] an..." wikitext text/x-wiki Those notes are from working on Reaperi Cycle and Summoning Signals, two projects that use primairly large textures for it's visual. Those projects are build using [[GLdc]] and a very light layer to interface with LUA. == Textures == I'm using ARGB1555 .dtex files for my test. At the moment of writing, all those textures are drawn in the TRANSLUCENT POLYGON LIST. I'm having trouble using the PUNCH-THRU LIST on GLdc == Fillrate == My calculation for fillrate is: (texture.width * texture.scale) * (texture.height * texture.scale) I mention this because although scaling the texture doesn't affect the memory bandwith, it does affect the rendering speed. Right now, anytime the fille rate reach +/- 550K, the framerate drops. 6dd672d34b9f7f96930b2e4d000c9a1c8c438902 874 873 2020-05-07T13:41:46Z Unknown user 0 wikitext text/x-wiki Those notes are from working on Reaperi Cycle and Summoning Signals, two projects that use primairly large textures for it's visual. Those projects are build using [[GLdc]] and a very light layer to interface with LUA. == Textures == I'm using ARGB1555 .dtex files for my test. At the moment of writing, all those textures are drawn in the TRANSLUCENT POLYGON LIST. == Fillrate == My calculation for fillrate is: (texture.width * texture.scale) * (texture.height * texture.scale) I mention this because although scaling the texture doesn't affect the memory bandwith, it does affect the rendering speed. There seems to be a direct relation between polygone size and rendering speed (read Tile-Accel. and Raster) * '''TRANSLUCENT LIST''' : 5-600K pixel before dipping under 60fps. * '''PUNCHTHRU LIST''' : 2.2M pixel before dipping under 60fps. == More Reading == [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=104287&p=1053299&hilit=Tile+Accelerator#p1053235 Tile-Accelerator and Rasterisation] 05085e436c698a65b9bddbd1c4c970a39aebd88d 881 874 2020-05-08T18:33:16Z Unknown user 0 wikitext text/x-wiki Those notes are from working on Reaperi Cycle and Summoning Signals, two projects that use primairly large textures for it's visual. Those projects are build using [[GLdc]] and a very light layer to interface with LUA. == Textures == I'm using ARGB1555 .dtex files for my test. At the moment of writing, all those textures are drawn in the TRANSLUCENT POLYGON LIST. == Fillrate == My calculation for fillrate is: (texture.width * texture.scale) * (texture.height * texture.scale) I mention this because although scaling the texture doesn't affect the memory bandwith, it does affect the rendering speed. There seems to be a direct relation between polygone size and rendering speed (read Tile-Accel. and Raster) ''In theory, this mean that drawing more smaller polygons is faster than drawing fewer larger polys, so using TRISTRIP can be quite useful here.'' * '''TRANSLUCENT LIST''' : 5-600K pixel before dipping under 60fps. * '''PUNCHTHRU LIST''' : 2.2M pixel before dipping under 60fps. == More Reading == [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=104287&p=1053299&hilit=Tile+Accelerator#p1053235 Tile-Accelerator and Rasterisation] cccf5f83930e4eba6e9a412a9ad15b5d96de9949 Internalized DreamPi adapter 0 276 876 2020-05-08T17:19:34Z Unknown user 0 Created page with "This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy mo..." wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem * C step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *1mm thick plastic washer *5mm thick plastic spacer You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs.: === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg b662f5346facbdf8b5b2a71f181cf5ec0a2d363f 877 876 2020-05-08T17:24:54Z Unknown user 0 /* Stuff you'll need */ wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem *DC step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *1mm thick plastic washer *5mm thick plastic spacer You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs.: === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg 773b7144c63d6842e11eec2aa8a650d1c92ea602 878 877 2020-05-08T17:27:00Z Unknown user 0 /* Stuff you'll need */ wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem *DC step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *3mm diameter plastic washer (like https://www.boltdepot.com/Product-Details.aspx?product=15944) *5mm thick plastic spacer (like https://www.boltdepot.com/Product-Details.aspx?product=13772) You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs.: === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg 1d121b6ab4fc0fa3632053909dfe62389f726901 879 878 2020-05-08T17:56:08Z Unknown user 0 wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. Forum post: https://dcemulation.org/phpBB/viewtopic.php?f=31&t=105525 https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem *DC step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *3mm diameter plastic washer (like https://www.boltdepot.com/Product-Details.aspx?product=15944) *5mm thick plastic spacer (like https://www.boltdepot.com/Product-Details.aspx?product=13772) You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs.: === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg 07440c132621c721ff59b669f9f6a8aba1717a70 880 879 2020-05-08T18:06:39Z Unknown user 0 /* Done! */ wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. Forum post: https://dcemulation.org/phpBB/viewtopic.php?f=31&t=105525 https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem *DC step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *3mm diameter plastic washer (like https://www.boltdepot.com/Product-Details.aspx?product=15944) *5mm thick plastic spacer (like https://www.boltdepot.com/Product-Details.aspx?product=13772) You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs.: === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg Note that there is a gap in time from the moment that the Dreamcast is powered on until the DreamPi is successfully booted and ready to accept incoming telephone connections. I timed this to be roughly 1 min 25 secs. So make sure you don't speed straight into your favorite game and dial right away or you'll get a few failures to connect until 1:25 has passed since the power button was pressed. In reality this isn't that big of an issue. I was able to sit in Phantasy Star Online for about 30 mins and the core temp of the Pi as measured over SSH did not exceed 59 C. I don't know how how this could get for many hours at maximum load, but top over SSH showed that the RPi sat around 50% idle when connected to an online game, so I don't believe the temperature would get up to dangerous levels. 35a023c92f46afa043c06f2f5252aecb72669d36 Internalized DreamPi adapter 0 276 882 880 2020-05-08T19:08:02Z Unknown user 0 /* Component miniaturization */ wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. Forum post: https://dcemulation.org/phpBB/viewtopic.php?f=31&t=105525 https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem *DC step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *3mm diameter plastic washer (like https://www.boltdepot.com/Product-Details.aspx?product=15944) *5mm thick plastic spacer (like https://www.boltdepot.com/Product-Details.aspx?product=13772) You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs. Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg Note that there is a gap in time from the moment that the Dreamcast is powered on until the DreamPi is successfully booted and ready to accept incoming telephone connections. I timed this to be roughly 1 min 25 secs. So make sure you don't speed straight into your favorite game and dial right away or you'll get a few failures to connect until 1:25 has passed since the power button was pressed. In reality this isn't that big of an issue. I was able to sit in Phantasy Star Online for about 30 mins and the core temp of the Pi as measured over SSH did not exceed 59 C. I don't know how how this could get for many hours at maximum load, but top over SSH showed that the RPi sat around 50% idle when connected to an online game, so I don't believe the temperature would get up to dangerous levels. 078e38b9c3787696296a1403ae3bcabbd1a0206e 884 882 2020-05-09T01:39:02Z Unknown user 0 wikitext text/x-wiki This will become a more thorough tutorial at a later point, but here is a work-in-progress basic rundown. Forum post: https://dcemulation.org/phpBB/viewtopic.php?f=31&t=105525 https://i.imgur.com/VmXnVJz.jpg I used a kiosk Dreamcast's dummy modem shell for this mod so that I wouldn't have a port on the back. These are obviously going to be difficult to come across, so you'll have to use a regular modem shell with a hole in it, and cosmetically doctor the hole somehow. Maybe a 3D printed snap-in panel? == Stuff you'll need == In order to do this, you need: *a Dreamcast modem (I used a revision A U.S. modem) *Dell NW147/Conexant RD02-D400 USB modem *DC step up board (like https://amazon.com/gp/product/B011EBSKK0) *0.47uF capacitor *380ohm resistor You can get away with other values for the cap and resistor, I used 1uF and 330ohm because that's what I had. You'll also need: *some kind of plastic glue (I used Gorilla Glue) *3mm diameter plastic washer (like https://www.boltdepot.com/Product-Details.aspx?product=15944) *5mm thick plastic spacer (like https://www.boltdepot.com/Product-Details.aspx?product=13772) You of course will need a multimeter, a soldering iron, flush cutters, etc. -- basic modding tools. Before you get started, make sure you set up your RPI with DreamPi as usual and make sure it works, your WiFi credentials are correct, etc. You don't want to have to troubleshoot DreamPi issues after you've cut everything up and made a million more variables for failure. == Shell prep == Using flush cutters, break out all the plastic supports except the leftmost screw post and the two short plastic posts on the far right. Glue the 1mm washer to the screwpost you left, and glue the two 5mm plastic spacers to the far right posts you left. After the glue dries, you can place the Dreamcast modem's PCB (discarding the part of the metal shell that typically sits there) on top of the spacers and see that it stands off evenly from the plastic and you can see quite a bit of space inside for the DreamPi stuff if you get creative enough. == Component miniaturization == Now you need to miniaturize your components. Everything that uses a plug or jack will now need to be direct wired by soldering to points on PCBs. Here is a picture I took while constructing mine, showing the USB modem, although parts of it are covered with tape in this pic: https://imgur.com/w3tTsRd === Dreamcast modem === *Desolder and remove the telephone jack. Take note of how the two pins left correspond to the two wires in a telephone line. *Pins 1, 2, 3, and 4 on the Dreamcast connector are all +5V. *Using your multimeter, identify +5V, ground, and the two telephone wire points on the exterior side of the modem. === USB modem === *Desolder and remove the telephone jack. Like the Dreamcast modem, take note of how the pins correspond to the two wires in a telephone line. *Desolder and remove the USB connector. Remember red wire is +5V, black wire is ground, green wire is data+, white wire is data-. *There are two blue capacitors on the board that make this board too thick to fit. Remove both capacitors, solder wires to the 4 points where the capacitors used to be, and solder to the capacitors to the wires, so that you can stuff these capacitors in an open spot in the modem. You might be able to find surface mount tiny replacement capacitors instead, but I didn't feel like doing that and just extended them and stuffed them away. There's enough space for it. === DC step up board === *This board is to apply the voltage to the 'telephone line' so the modem sees it as an active telephone line. Apply 5V and ground to this board and use your multimeter to tweak the voltage setting on the screw. I used 9V for my U.S. modem, but PAL modems need 18V. *Desolder and remove the microUSB plug on this board. It might not seem like much but I was able to get some needed space by doing this. *Take note that on the input side, the board needs +5V and ground, and the output side will be for the capacitor, resistor, and one of the telephone lines in and out. === Raspberry Pi === *You don't need to desolder anything from this board. On the bottom, you'll see PP1 is +5V, PP6 is ground, PP22 is USB D+, and PP23 is USB D-. Identify and remember these points. https://imgur.com/8y4jmmK == Soldering time == Take your time with this, plan out how you want to connect everything, make sure everything is going to fit as you do it. Make sure that you don't glue anything against the edges of the plastic as the metal shielding will slide in there when you put it back together. This is just a list of what you're doing, not necessarily in any particular order: *Use the 5V and ground points you identified on the Dreamcast modem to supply 5V and ground to the RPi, the USB modem, and the DC transformer input. *Connect the D+ and D- points on the USB modem board to the D+ and D- points on the RPi. *Voltage inducement: Observe the following image that shows the construction of a battery-based line voltage inducer: https://imgur.com/W4r18Ph Using this as a reference, with the battery connection terminals representing the V+ and V- output side of the DC transformer, construct the line voltage inducement circuit. The telephone line is like a circular loop: Pin 1 from the Dreamcast modem goes through this circuit to add voltage and connects to pin 2 on the USB modem; pin 1 on the USB modem directly connects to the pin 2 on the Dreamcast modem. A better, more illustrated diagram will come later. Here is what mine looked like after soldering was finished and I determined the whole thing worked, but I hadn't put it together yet: https://i.imgur.com/RFgUa3Q.jpg The image is very messy as it was taken after running into a few snags and having to rip it apart and put it back together again. But what you see in the image works perfectly. == Assembly == You may want to use electrical tape or some other insulator to protect the boards from one another. I just put strips of electrical tape securely on the RPi. Place the RPi board on top of the USB modem, and then place the Dreamcast modem on top of the plastic standoffs. Carefully replace the metal shielding. You will then screw this together using the one remaining screw post you didn't remove. The left side will be secure, while the right side will be slightly coming apart. Using some tape, very tightly apply tape the right side corner. You want the tape to be tight because if you loosely tape this, your DreamWiFi will slightly protrude from the console 1-2mm. It won't affect the function, but aren't you doing all this work so everything looks cool? == Done! == https://i.imgur.com/5p2IHku.jpg<br /> https://i.imgur.com/nnnr8vX.jpg Note that there is a gap in time from the moment that the Dreamcast is powered on until the DreamPi is successfully booted and ready to accept incoming telephone connections. I timed this to be roughly 1 min 25 secs. So make sure you don't speed straight into your favorite game and dial right away or you'll get a few failures to connect until 1:25 has passed since the power button was pressed. In reality this isn't that big of an issue. == Temperature analysis == I was able to sit in Phantasy Star Online for about 30 mins and the core temp of the Pi as measured over SSH did not exceed 59 C. I don't know how how this could get for many hours at maximum load, but top over SSH showed that the RPi sat around 50% idle when connected to an online game, so I don't believe the temperature would get up to dangerous levels. Update on this part: I left the DC on for 10 hours at the PSO title screen loop to get all nice and warm, then came back to it and connected to PSO and basically sat in the lobby connected for an hour and a half, while also pinging the Dreamcast's IP over and over from my desktop computer. The temperature so far has not gotten above 65.9 C, and mostly lingers around 64-65 now. I haven't had any packets dropped while pinging all this time. I'm pretty confident the temperatures and performance will be safe long term. 9e298cf50bbba0e0cc7694a21dd8dd986f088d13 Broadband adapter 0 5 883 836 2020-05-08T21:52:57Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black ones were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white ones<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Note that all broadband adapters are the same between regions, right down to the FCC sticker on the bottom of the unit. The only difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese box also included the Broadband Passport web browser. One could therefore say that all broadband adapters are technically "North American" models. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. The Dreamcast [[Karaoke|Karaoke Unit]] also could access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == a2d5768184054d80c8aabc56cebaa9ebe8d4250d 885 883 2020-05-09T20:15:35Z Unknown user 0 Estimate BBAs, add some new info found wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black ones were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white ones<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Note that, hardware-wise, all broadband adapters are identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and therefore are not region-locked. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them.<ref>It appears that those lacking the FCC logo were likely built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." This is purely a cosmetic difference.</ref> The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese box also included the Broadband Passport web browser. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. The Dreamcast [[Karaoke|Karaoke Unit]] also could access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work. Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are meant to be unique, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == c6765872f67e656153f230711df2db7fff8dc936 886 885 2020-05-09T20:17:38Z Unknown user 0 wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Broadband Adapters were made in both black and white colors, although the black ones were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black ones were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white ones<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Note that, hardware-wise, all broadband adapters are identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and therefore are not region-locked. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them.<ref>It appears that those lacking the FCC logo were likely built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." This is purely a cosmetic difference.</ref> The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese box also included the Broadband Passport web browser. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming, debugging, and dumping [[GD-ROM|GD-ROMs]]. The Dreamcast [[Karaoke|Karaoke Unit]] also could access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == ddf34db4b4c59dfbb0a0d7c81dd9cbb0c66574d4 887 886 2020-05-09T20:36:37Z Unknown user 0 Getting big, so add sections wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games,<ref>https://www.dreamcastlive.net/games</ref> but they are useful for playing supported networked games and linking to a computer for programming and debugging software, as well as dumping [[GD-ROM|GD-ROMs]]. In Japan, the Dreamcast [[Karaoke|Karaoke Unit]] also could access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> === Regional Differences === The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese boxes also included the Broadband Passport web browser. Hardware-wise, all broadband adapters are functionally identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and are not region-locked in any way. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them. It appears that those lacking the FCC logo were likely just built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." === Availability === Broadband Adapters were made in both black and white colors, although the black models were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black adapters were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white adapters<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == db41a8873256e141118480c796ec85960f4df386 888 887 2020-05-09T20:51:53Z Unknown user 0 That looks and reads a lot better wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. == Software Support == Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games (see https://www.dreamcastlive.net/games for a list), but they are useful for playing supported networked games and linking to a computer for programming and debugging software (via [[dcload-ip]]), as well as dumping [[GD-ROM|GD-ROMs]]. In Japan, the Dreamcast [[Karaoke|Karaoke Unit]] could also access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Software made using the open-source [[KallistiOS]] development environment has access to a broadband adapter driver, as well.<ref>https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/hardware/network/broadband_adapter.c</ref> == Regional Differences == The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese boxes also included the Broadband Passport web browser. Hardware-wise, all broadband adapters are functionally identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and are not region-locked in any way. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them. It appears that those lacking the FCC logo were likely just built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." === Availability === Broadband Adapters were made in both black and white colors, although the black models were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black adapters were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white adapters<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == febed222e1d453e5f014df903603e073310359ef 889 888 2020-05-09T21:56:36Z Unknown user 0 Add hardware section wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. == Software Support == Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games (see https://www.dreamcastlive.net/games for a list). They are also useful for linking to a computer for programming and debugging software (via [[dcload-ip]]), as well as dumping [[GD-ROM|GD-ROMs]] (via [[httpd-ack]]). In Japan, the Dreamcast [[Karaoke|Karaoke Unit]] could also access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Software made using the open-source [[KallistiOS]] development environment has access to a broadband adapter driver, as well.<ref>https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/hardware/network/broadband_adapter.c</ref> == Regional Differences == The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese boxes also included the Broadband Passport web browser. Hardware-wise, all broadband adapters are functionally identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and are not region-locked in any way. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them. It appears that those lacking the FCC logo were likely just built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." === Availability === Broadband Adapters were made in both black and white colors, although the black models were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black adapters were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white adapters<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Hardware == The broadband adapter layout is rather simple, being comprised of a very common and inexpensive Realtek RTL8139C 10/100mbps PCI ethernet controller and a custom, SEGA-branded G2-to-PCI bridge chip (often referred to as "GAPS" due to containing the identification string "GAPSPCI_BRIDGE_2"), plus additional supporting circuitry such as a Pulse H0011 isolation transformer, 25MHz crystal oscillator, etc. Due to the various hardware security measures in place, the GAPS PCI bridge chip has proven very difficult to reverse-engineer, stifling several efforts to make "clone" BBAs over the years. The difficulty in programming the chip has also resulted in incorrect implementations in all known open-source drivers, leading to significantly reduced performance (something like 24Mbps when the chip is actually capable of the full 100Mbps) and inconsistent open-source documentation, motivating a months-long effort by the author of this sentence to better understand the hardware and completely overhaul dcload-ip<ref>https://github.com/Moopthehedgehog/dcload-ip</ref> (Note: still ongoing--this bridge chip is insane). Of note, it is not likely that the bridge chip itself would be useful in designing arbitrary PCI peripherals for the Dreamcast, as certain security measures appear to be essentially "hardcoded" into the hardware for the RTL8139C. The bus also only runs at 25MHz, as the bridge chip does not appear to do any kind of intermediary frequency conversion to conventional 33 or 66 MHz PCI, though the RTL8139C can handle bus speeds of 16.75MHz to 40MHz just fine<ref>See https://people.freebsd.org/~wpaul/RealTek/spec-8139c(160).pdf, page 2</ref>. As a result, understanding the operation of the bridge is really only useful for programming broadband adapter drivers. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == 4186d04814fc1df7e42b7ea48478f7b3bfe8cb54 890 889 2020-05-09T22:08:46Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. == Software Support == Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games (see https://www.dreamcastlive.net/games for a list). They are also useful for linking to a computer for programming and debugging software (via [[dcload-ip]]), as well as dumping [[GD-ROM|GD-ROMs]] (via [[httpd-ack]]). In Japan, the Dreamcast [[Karaoke|Karaoke Unit]] could also access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Software made using the open-source [[KallistiOS]] development environment has access to a broadband adapter driver, as well.<ref>https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/hardware/network/broadband_adapter.c</ref> == Regional Differences == The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese boxes also included the Broadband Passport web browser. Hardware-wise, all broadband adapters are functionally identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and are not region-locked in any way. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them. It appears that those lacking the FCC logo were likely just built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." === Availability === Broadband Adapters were made in both black and white colors, although the black models were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black adapters were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white adapters<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Hardware == The broadband adapter layout is rather simple, being comprised of a very common and inexpensive Realtek RTL8139C 10/100mbps PCI ethernet controller and a custom, SEGA-branded G2-to-PCI bridge chip (often referred to as "GAPS" due to containing the identification string "GAPSPCI_BRIDGE_2"), plus additional supporting circuitry such as a Pulse H0011 isolation transformer, 25MHz crystal oscillator, etc. Due to the various hardware security measures in place, the GAPS PCI bridge chip has proven very difficult to reverse-engineer, stifling several efforts to make "clone" BBAs over the years. The difficulty in programming the chip has also resulted in incorrect implementations in all known open-source drivers, leading to significantly reduced performance (something like 24Mbps when the chip is actually capable of the full 100Mbps) and inconsistent open-source documentation, motivating a months-long effort by the author of this sentence to better understand the hardware and completely overhaul dcload-ip<ref>https://github.com/Moopthehedgehog/dcload-ip</ref> (Note: still ongoing--this bridge chip is insane). Of note, it is not likely that the bridge chip itself would be useful in designing arbitrary PCI peripherals for the Dreamcast; certain security measures appear to be essentially "hardcoded" into the hardware for the RTL8139C. The PCI side may also only run at 25MHz, as the bridge chip does not appear to do any intermediary frequency conversion to PCI's conventional 33 or 66 MHz. The RTL8139C can handle bus speeds of 16.75MHz to 40MHz just fine, in any case.<ref>See https://people.freebsd.org/~wpaul/RealTek/spec-8139c(160).pdf, page 2</ref> As a result, understanding the operation of the bridge is really only useful for programming broadband adapter drivers. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == afe045cbf210be07a2c30c503f2cb8ace7f58537 891 890 2020-05-09T22:10:11Z Unknown user 0 /* Hardware */ -- Misplaced a period wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. == Software Support == Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games (see https://www.dreamcastlive.net/games for a list). They are also useful for linking to a computer for programming and debugging software (via [[dcload-ip]]), as well as dumping [[GD-ROM|GD-ROMs]] (via [[httpd-ack]]). In Japan, the Dreamcast [[Karaoke|Karaoke Unit]] could also access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Software made using the open-source [[KallistiOS]] development environment has access to a broadband adapter driver, as well.<ref>https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/hardware/network/broadband_adapter.c</ref> == Regional Differences == The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese boxes also included the Broadband Passport web browser. Hardware-wise, all broadband adapters are functionally identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and are not region-locked in any way. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them. It appears that those lacking the FCC logo were likely just built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." === Availability === Broadband Adapters were made in both black and white colors, although the black models were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black adapters were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white adapters<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or 131,072 total BBAs and LAN adapters produced. == Hardware == The broadband adapter layout is rather simple, being comprised of a very common and inexpensive Realtek RTL8139C 10/100mbps PCI ethernet controller and a custom, SEGA-branded G2-to-PCI bridge chip (often referred to as "GAPS" due to containing the identification string "GAPSPCI_BRIDGE_2"), plus additional supporting circuitry such as a Pulse H0011 isolation transformer, 25MHz crystal oscillator, etc. Due to the various hardware security measures in place, the GAPS PCI bridge chip has proven very difficult to reverse-engineer, stifling several efforts to make "clone" BBAs over the years. The difficulty in programming the chip has also resulted in incorrect implementations in all known open-source drivers, leading to significantly reduced performance (something like 24Mbps when the chip is actually capable of the full 100Mbps) and inconsistent open-source documentation, motivating a months-long effort by the author of this sentence to better understand the hardware and completely overhaul dcload-ip (Note: still ongoing--this bridge chip is insane).<ref>https://github.com/Moopthehedgehog/dcload-ip</ref> Of note, it is not likely that the bridge chip itself would be useful in designing arbitrary PCI peripherals for the Dreamcast; certain security measures appear to be essentially "hardcoded" into the hardware for the RTL8139C. The PCI side may also only run at 25MHz, as the bridge chip does not appear to do any intermediary frequency conversion to PCI's conventional 33 or 66 MHz. The RTL8139C can handle bus speeds of 16.75MHz to 40MHz just fine, in any case.<ref>See https://people.freebsd.org/~wpaul/RealTek/spec-8139c(160).pdf, page 2</ref> As a result, understanding the operation of the bridge is really only useful for programming broadband adapter drivers. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == 6d973954abbc420a7709eaa6bbe8fa96543a1544 892 891 2020-05-09T23:00:44Z Unknown user 0 /* Regional Differences */ Add Fermi Estimation notice wikitext text/x-wiki [[File:58747972.png|thumb|A black Dreamcast broadband adapter]] The Dreamcast '''Broadband Adapter''' ('''HIT-400''', sometimes '''HIT-401'''; HIT-401 is written on the Japanese box, but HIT-400 is on the peripheral's underside sticker), often abbreviated '''BBA''', is a 10/100mbit network adapter for the Dreamcast based on the Realtek 8139C chip. It connects to the G2 bus in place of the modem, and it was released in Japan and in the United States. Despite not seeing a release in PAL regions, some PAL game software is actually compatible with it, such as Toy Racer and Phantasy Star Online.<ref>https://www.dreamcastlive.net/games</ref> It is a different piece of hardware than the [[LAN adapter | Dreamcast LAN Adapter]]. == Software Support == Due to their release towards the end of the Dreamcast's official lifespan, broadband adapters are somewhat uncommon peripherals and are only supported by a handful of games (see https://www.dreamcastlive.net/games for a list). They are also useful for linking to a computer for programming and debugging software (via [[dcload-ip]]), as well as dumping [[GD-ROM|GD-ROMs]] (via [[httpd-ack]]). In Japan, the Dreamcast [[Karaoke|Karaoke Unit]] could also access the DreamKara service by way of the Broadband Adapter.<ref>For some reason the text on this page is white on a white background. Highlight the whole page to see it: http://web.archive.org/web/20010413170305/http://www.sega.co.jp/sega/kara/dc_kara/bba/bba.html</ref> Software made using the open-source [[KallistiOS]] development environment has access to a broadband adapter driver, as well.<ref>https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/hardware/network/broadband_adapter.c</ref> == Regional Differences == The only major difference between the Japanese and North American releases was the packaging, as they had different boxes and manuals, and the Japanese boxes also included the Broadband Passport web browser. Hardware-wise, all broadband adapters are functionally identical (except MAC addresses, as those are meant to be unique to each device<ref>"The Ethernet - A Local Area Network", Version 2.0, Digital Equipment Corporation, Intel Corporation, Xerox Corporation, November 1982, p. 24.</ref>) and are not region-locked in any way. In many cases, they even have the same FCC sticker on the bottom of each unit irrespective of the region in which they were sold, although some have a sticker without the FCC logo on them. It appears that those lacking the FCC logo were likely just built before Sega Enterprises became Sega Corporation in November 2000, as they state "Sega Enterprises" instead of "Sega Corporation." === Availability === Broadband Adapters were made in both black and white colors, although the black models were only available via online order from CSI in Japan.<ref>http://web.archive.org/web/20020402231233/http://www3.csi-msp.com:80/bbsite/</ref> Fewer than 2000 black adapters were made due to low demand during the window of opportunity to pre-order them (December 1, 2001 to December 28, 2001), and they cost 8,800 yen (the same price as the white adapters<ref>https://www.ign.com/articles/2000/06/16/dreamcast-broadband-on-display</ref>).<ref>http://web.archive.org/web/20011227174405/http://www3.csi-msp.com/bbsite/web/news/news54.html</ref> Also, an R7 Limited Edition console + broadband adapter bundle was sold by CSI for a limited time, however it is not clear if these consoles were sold with black adapters.<ref>http://web.archive.org/web/20020816021110/http://www3.csi-msp.com/bbsite/web/news/news69.html</ref> Contrary to popular belief, in Japan broadband adapters were only sold by CSI, not by Sega themselves.<ref>http://web.archive.org/web/20020606141349/http://www.sega.co.jp:80/bba/where.html</ref> In the US, however, they could be bought in stores or from Sega's online store for $60.<ref>http://web.archive.org/web/20010331175923/http://www.sega.com/sega/segastore/index.jhtml</ref> '''''NOTICE: Due to the lack of exact production numbers, the below estimates are determined by a technique known as "Fermi estimation,"<ref>https://en.wikipedia.org/wiki/Fermi_problem</ref> which uses available data to estimate order of magnitude rather than calculate perfectly accurate numbers.''''' Though there is no direct source for the exact number of broadband adapters produced, it is actually possible to estimate how many there are due to the way in which MAC addresses work: Each MAC address consists of 6 bytes AA:BB:CC:DD:EE:FF, with the leading bytes all 00:d0:f1 (the MAC address range owned by SEGA). The next 3 bytes are unique per-device, and it appears that all broadband adapters have '02' or '03' in byte 'DD'. Dreamcast LAN Adapters appear to share the '02' byte. Since 2 bytes hold 65,536 values, this means that within each '02' and '03' MAC address group there are 65,536 possible devices. As it is currently unknown if there are '00' or '01' groups, this means we can estimate that there are potentially 2 groups of 65,536 adapters, or a maximum of 131,072 total BBAs and LAN adapters produced. We can actually take this estimate further: if the networking adapters are assumed produced in sequential MAC address order, the author of this sentence owns a LAN adapter whose address would suggest something like 4800 LAN adapters were produced. Black broadband adapters, which were among the last produced in 2001, have addresses suggesting around 24,000 devices in group '03'. By the presence of group '03', group '02' was likely full, which would mean a more specific total of roughly 90,000 networking adapters (~4800 LAN adapters, <2000 black BBAs, and ~83,000 white BBAs). == Hardware == The broadband adapter layout is rather simple, being comprised of a very common and inexpensive Realtek RTL8139C 10/100mbps PCI ethernet controller and a custom, SEGA-branded G2-to-PCI bridge chip (often referred to as "GAPS" due to containing the identification string "GAPSPCI_BRIDGE_2"), plus additional supporting circuitry such as a Pulse H0011 isolation transformer, 25MHz crystal oscillator, etc. Due to the various hardware security measures in place, the GAPS PCI bridge chip has proven very difficult to reverse-engineer, stifling several efforts to make "clone" BBAs over the years. The difficulty in programming the chip has also resulted in incorrect implementations in all known open-source drivers, leading to significantly reduced performance (something like 24Mbps when the chip is actually capable of the full 100Mbps) and inconsistent open-source documentation, motivating a months-long effort by the author of this sentence to better understand the hardware and completely overhaul dcload-ip (Note: still ongoing--this bridge chip is insane).<ref>https://github.com/Moopthehedgehog/dcload-ip</ref> Of note, it is not likely that the bridge chip itself would be useful in designing arbitrary PCI peripherals for the Dreamcast; certain security measures appear to be essentially "hardcoded" into the hardware for the RTL8139C. The PCI side may also only run at 25MHz, as the bridge chip does not appear to do any intermediary frequency conversion to PCI's conventional 33 or 66 MHz. The RTL8139C can handle bus speeds of 16.75MHz to 40MHz just fine, in any case.<ref>See https://people.freebsd.org/~wpaul/RealTek/spec-8139c(160).pdf, page 2</ref> As a result, understanding the operation of the bridge is really only useful for programming broadband adapter drivers. == Tools == * [[dcload-ip]] - A program made to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. Mostly intended for homebrew development. * [[httpd-ack]] - Most highly recommended [[GD-ROM]] dumping software * [[:File:Bbrip v1.2.zip|BBRip v1.2]] - Now-obsolete Windows-only [[GD-ROM]] dumping software for use with [[dcload-ip]] (it is recommended to use httpd-ack instead) == Documents == * [[:File:Spec-8139c(160).pdf|Realtek RTL8139C datasheet]] == References == c58850db5688c65544bdf2387ef8db6c567dbc39 DreamPi PF Configuration Example 0 274 893 871 2020-05-10T16:30:38Z Unknown user 0 wikitext text/x-wiki This is an example of how I set up an OpenBSD router to work with all games on DreamPi 1.7. These settings should be similar to what's necessary for a pfSense or FreeBSD based router. *On your DreamPi, put an empty file named /boot/ssh on the card and boot the DreamPi in order to enable ssh. *SSH into the DreamPi using username: pi and password: raspberry, and make sure to change the password using "sudo passwd pi" *On your Raspberry Pi, stop the DreamPi service with "sudo service dreampi stop" *Use nano to edit the dreampi.py configuration: "sudo nano /home/pi/dreampi/dreampi.py" *Find these lines: <pre>this_ip = find_next_unused_ip(".".join(subnet) + ".100") dreamcast_ip = find_next_unused_ip(this_ip)</pre> *Replace with: <pre>#this_ip = find_next_unused_ip(".".join(subnet) + ".100") #dreamcast_ip = find_next_unused_ip(this_ip) this_ip = "192.168.1.19" dreamcast_ip = "192.168.1.20"</pre> In this example, 192.168.1.19 is the IP address you want to use for your DreamPi modem's IP address, and 192.168.1.20 is the IP address you want to use for your Dreamcast. Make sure you pick an IP not within your DHCP pool. *Save the file. *Start the DreamPi service with "sudo service dreampi start" *The DreamPi will now always use the same IP address, so it will now be easier to configure your PF firewall. *Here are the following relevant entries from my /etc/pf.conf: <pre>#define dreamcast/dreampi ipv4 address dreamcast = 192.168.1.20 # dreampi at 192.168.1.19 # dreamcast ports to forward # AFO: UDP 7980 # ChuChuRocket: UDP 9789 # IGP: UDP 5656, TCP 5011, TCP 10500, TCP 10501-10503 # 2K: UDP 5502, UDP 5503, UDP 5656, TCP 5011, TCP 6666 # NextTetris: TCP/UDP 3512 # OogaBooga: UDP 6001 # PBA2001: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624, UDP 13139 # Planet Ring: UDP 7648, UDP 1285, UDP 1028 # Starlancer: TCP/UDP 2300-2400, UDP 6500, TCP/UDP 47624 # WSB 2K2: UDP 37171, UDP 13713 # Worms World Party: TCP 17219 dreamcast_udp_ports = "{ 1028, 1285, 2300:2400, 3512, 5502:5503, 5656, 6001, 6500, 7648, 7980, 9789, 13139, 13713, 37171, 47624 }" dreamcast_tcp_ports = "{ 2300:2400, 3512, 5011, 6666, 10500:10503, 17219, 47624 }" #ext_if is the name of the external interface, e.g. ext_if = "re0" match out on $ext_if inet from $dreamcast nat-to ($ext_if) static-port pass in on $ext_if inet proto udp from any to any port $dreamcast_udp_ports rdr-to $dreamcast pass in on $ext_if inet proto tcp from any to any port $dreamcast_tcp_ports rdr-to $dreamcast</pre> *Restart pf entirely with "pfctl -F all -f /etc/pf.conf" on your BSD machine. *Your DreamPi should now be able to connect to all of the online games currently available. When new games become available in the future, you may need to update your pf.conf rules to allow these new games through. 490f74ffa7215e26191ce3da4b57538b3d05db6e Battery replacement 0 96 894 867 2020-05-11T16:09:27Z Unknown user 0 Explain the more obscure sizes wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of the ML2032 in the future. It is recommended '''not''' to use the LIR2032 battery type as the Dreamcast does not output the voltage necessary for it to properly and fully recharge. Specifically, the ML2020, ML2032, and ML2430 are 3V batteries, with ML2020 being the smallest,<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> ML2032 in the middle (recommended),<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> and ML2430 being the largest (it may be too physically large to fit with an appropriately-sized reusable coin cell holder, however)<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref>, while the LIR2032 type is generally 3.6V or 3.7V.<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> == Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 0fcf57de680ad342decc8c905c86b41cca613733 895 894 2020-05-11T16:22:11Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery such as ML2032 in the future. It is recommended '''not''' to use the LIR2032 battery type as the Dreamcast does not output the voltage necessary for it to properly and fully recharge. Specifically, the ML2020, ML2032, and ML2430 are all compatible 3V batteries with differing capacities and physical sizes (with larger number meaning larger capacity and physical size),<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref><ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref><ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> while the LIR2032 type is generally 3.6V or 3.7V.<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Note that the ML2430 may be too large to fit with an appropriately-sized reusable battery holder, and as such ML2032 is the recommended replacement type. == Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == a87c95c2a5f7e9947492b06e3aa3b0cb42fbdf49 897 895 2020-05-11T16:29:54Z Unknown user 0 Add some specs in-line wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery such as ML2032 in the future. It is recommended '''not''' to use the LIR2032 battery type as the Dreamcast does not output the voltage necessary for it to properly and fully recharge. Specifically, the ML2020, ML2032, and ML2430 are all compatible 3V batteries with differing capacities and physical sizes (Note: a larger number indicates a larger capacity and physical size, with ML2020 at 45mAh and 20mm x 2mm, ML2032 at 65mAh and 20mm x 3.2mm, and ML2430 at 100mAh and 24.5mm x 3.0mm),<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref><ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref><ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> while the LIR2032 type is generally 3.6V or 3.7V.<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Note that the ML2430 may be too large to fit with an appropriately-sized reusable battery holder, and as such ML2032 is the recommended replacement type. == Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 356cb3bd6b4bafd0ad2c6d4a0cc32f8dd000b4af 900 897 2020-05-11T16:38:46Z Unknown user 0 That looks and reads better than before, I think wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, not 3V<ref>https://www.powerstream.com/p/Lir2032.pdf</ref>). Instead, ML2020, ML2032, and ML2430 coin cells are all compatible 3V batteries of differing capacities and physical sizes, where a larger model number indicates a larger capacity and physical size: ML2020 is 45mAh and 20mm x 2mm, ML2032 is 65mAh and 20mm x 3.2mm, and ML2430 is 100mAh and 24.5mm x 3.0mm.<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref><ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref><ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> Note that the ML2430 may be too large to fit with an appropriately-sized reusable battery holder, and as such ML2032 is the recommended replacement type. == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 82a0ab35ee991519a25392182cdf853c8c6496da 903 900 2020-05-11T16:52:55Z Unknown user 0 Pretty Table! wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's time and date settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes: {| class="wikitable" ! Model ! Capacity (mAh) ! Physical Size (mm x mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized reusable battery holder, and as such ML2032 is the recommended replacement type. == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == ceb298b0edd927ff83d6524542758f527dc54cee 904 903 2020-05-11T16:53:45Z Unknown user 0 Consistency in noun ordering wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's date and time settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes: {| class="wikitable" ! Model ! Capacity (mAh) ! Physical Size (mm x mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized reusable battery holder, and as such ML2032 is the recommended replacement type. == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 19ed2d9892493294048f6c4827521d783047e4a7 905 904 2020-05-11T17:00:12Z Unknown user 0 clarify that the ML2430 that sometimes is in there is a soldered-in type wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger soldered-in ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's date and time settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes: {| class="wikitable" ! Model ! Capacity (mAh) ! Physical Size (mm x mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized reusable battery holder, and as such ML2032 is the recommended replacement type. The soldered-in ML2430 type does fit, however, as some consoles came with those instead of the soldered-in ML2020 type. == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == a10b9fb359032f4cc19c16e240132efc545592c8 906 905 2020-05-11T17:03:54Z Unknown user 0 Specify vertical orientation as the issue for the ML2430s wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger soldered-in ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's date and time settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes: {| class="wikitable" ! Model ! Capacity (mAh) ! Physical Size (mm x mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized, vertical reusable battery holder, and as such ML2032 is the recommended replacement type. The vertically-oriented, soldered-in ML2430 type does fit, however, as some consoles came with those instead of the soldered-in ML2020 type. == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == d992850fb30db01f4c45b817af5e6297d90c68cc 907 906 2020-05-11T17:08:44Z Unknown user 0 wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger soldered-in ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's date and time settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes: {| class="wikitable" ! Model ! Capacity (mAh) ! Physical Size (mm x mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized, vertical reusable battery holder, and as such ML2032 is the recommended replacement type. The vertically-oriented, soldered-in ML2430 type does fit, however, as some consoles came with those instead of the soldered-in ML2020 type.<ref>My R7 console did. --Moopthehedgehog</ref> == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == bc669e2e62c12d68cad337bc816a5433523fc34e 908 907 2020-05-11T17:59:18Z Unknown user 0 /* Compatible Batteries */ -- Table units are nice, but they're better when they also mention which measurement corresponds to which dimension wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger soldered-in ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's date and time settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes: {| class="wikitable" ! Model ! Capacity<br>(mAh) ! Physical Size<br>diameter (mm) x height (mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized, vertical reusable battery holder, and as such ML2032 is the recommended replacement type. The vertically-oriented, soldered-in ML2430 type does fit, however, as some consoles came with those instead of the soldered-in ML2020 type.<ref>My R7 console did. --Moopthehedgehog</ref> == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 9e6db92492d6b3b1815a0962b3aa5a48618450ac 909 908 2020-05-11T18:00:11Z Unknown user 0 /* Compatible Batteries */ wikitext text/x-wiki [[File:Dreamcast controller board rear view.png|645px|thumb|center|Rear view of a Dreamcast controller board; note the battery by default is a soldered-in ML2020, or sometimes a larger soldered-in ML2430.]] The Dreamcast uses a soldered-in, rechargeable battery to store the console's date and time settings. The battery recharges whenever the console is powered on, takes about 2 hours to charge from empty to full, and should hold date and time settings for about 20 days.<ref>Page 12, "Rechargeable Battery": https://archive.org/details/DreamCast_Instruction_Manual_2000_Sega_US/page/n11/mode/2up</ref> The batteries on most all Dreamcast consoles should be totally dead by now, so one can desolder the original battery and replace it with a plastic battery holder to allow easy replacement of a compatible battery, such as ML2032, in the future. == Compatible Batteries == It is highly recommended '''NOT''' to use the LIR2032 battery type, as the Dreamcast does not output the voltage necessary for it to properly and fully recharge (LIR2032 are 3.6-3.7V batteries, rather than 3V).<ref>https://www.powerstream.com/p/Lir2032.pdf</ref> Instead, ML2020, ML2032, and ML2430 coin cells should be used, as they are all rechargeable 3V batteries of differing capacities and physical sizes per the following table: {| class="wikitable" ! Model ! Capacity<br>(mAh) ! Physical Size<br>diameter (mm) x height (mm) ! Datasheet |- | ML2020 || 45 || 20 x 2 ||<ref>https://na.industrial.panasonic.com/products/batteries/rechargeable-batteries/lineup/rechargeable-coin/series/90797/model/90809</ref> |- | ML2032 || 65 || 20 x 3.2 ||<ref>http://www.maxell.com.tw/images/uploads/2015/05/ML2032_DataSheet_table.pdf</ref> |- | ML2430 || 100 || 24.5 x 3.0 ||<ref>https://media.digikey.com/pdf/Data%20Sheets/FDK/ML2430.PDF</ref> |} Note that the ML2430 may be too large to fit with an appropriately-sized, vertical reusable battery holder, and as such ML2032 is the recommended replacement type. The vertically-oriented, soldered-in ML2430 type does fit, however, as some consoles came with those instead of the soldered-in ML2020 type.<ref>My R7 console did. --Moopthehedgehog</ref> == Recommended Parts == * Standard vertical CR2032 battery holders such as these have the same footprint as the stock, soldered-in battery: https://console5.com/store/vertical-holder-for-2032-batteries.html * ML2032 batteries can be found online from various places. == References == 74b7a493eae4deb6d12214e1093c6c9a0fa8a67a Useful programming tips 0 269 896 846 2020-05-11T16:27:09Z Unknown user 0 wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: <code> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </code> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do this to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero extend, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == == Functions and registers == == References == aef216f43d6e287983612af87f9def264f6d7fe1 898 896 2020-05-11T16:30:29Z Unknown user 0 /* Functions and registers */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: <code> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </code> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do this to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero extend, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == == Functions and registers == The first 8 floats and 4 ints are going to in the registrers. Anything else uses the stack. Using struct pointer? mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 93fca9d37aafda1e663fff2d6cd4ba7c13946c9a 899 898 2020-05-11T16:33:45Z Unknown user 0 /* Alignment */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: <code> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </code> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do this to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero extend, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == == Functions and registers == The first 8 floats and 4 ints are going to in the registrers. Anything else uses the stack. Using struct pointer? mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == e4e34f7164afcb402db9026f3b11031e316d4022 901 899 2020-05-11T16:44:46Z Unknown user 0 /* Functions and registers */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: <code> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </code> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do this to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero extend, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == == Functions and registers == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 158190e57f015aa67002c87b0fc4ac9fbd3d9a7c 902 901 2020-05-11T16:45:49Z Unknown user 0 /* Alignment */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do this to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero extend, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add, mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == == Functions and registers == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 94ff145f0ae9d75eab6bfe58cca98d0fc4bb30b4 910 902 2020-05-11T18:06:22Z Unknown user 0 /* Alignment */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == == Functions and registers == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 2628065c2a9d71ff91775192b829d0116f1143ac 911 910 2020-05-11T18:28:49Z Unknown user 0 /* Cache Management */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == Functions and registers == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 864bdfb319c374159d9e2f5cfd4e81823cd6a5d1 912 911 2020-05-11T18:38:39Z Unknown user 0 Add RTFM, we're not rehashing the manuals here--this page is mainly to help with practical usage of the chip wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals. Both documents can be downloaded from the "Documents" section of any SH7750 series process on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html). A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == Functions and registers == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == d6ea36b965e61fde9f2b7092e3e662c3d9d3cb70 913 912 2020-05-11T18:39:12Z Unknown user 0 /* Functions and registers */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals. Both documents can be downloaded from the "Documents" section of any SH7750 series process on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html). A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == Register Allocation == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == cff273163d5383eed4a345d0fb4c0f1921266c34 914 913 2020-05-11T18:44:07Z Unknown user 0 Yay, documents! wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series process on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == Register Allocation == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 1ce63b8949e22143229a9ce0303694f1780620e1 915 914 2020-05-11T18:44:56Z Unknown user 0 wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == Register Allocation == The first 8 floats and 4 ints are going to in the registers. Anything else uses the stack. Using struct pointer is also good. You can prefetch it using a local variable. Each read to this struct is gonna cost 2 cycle. mrneo240: It's 8 floats? [11:14 AM] Moopthehedgehog: yes [11:14 AM] DanB91: yea i remember hearing register allocation used to be terrible in gcc but now it's pretty good [11:15 AM] Moopthehedgehog: I haven't had any problems with it [11:15 AM] Moopthehedgehog: but in addition to those passed in, you get 4 ints to use as local variables [11:15 AM] mrneo240: So if I pass 6 args, in an int situation pass struct by pointer but for floats just pass all in arguments [11:16 AM] Moopthehedgehog: well, it depends. If the first four are used more than the last two, you can still benefit from passing those first 4 in regs [11:16 AM] Moopthehedgehog: in write-back memory the last two will be passed on stack in the cache [11:17 AM] Moopthehedgehog: however, if they cause the stack to cross a cacheline, they'll cause a cache fetch, and that's gonna be a hidden perf cost [11:17 AM] Moopthehedgehog: if you pass a pointer to a struct, and you prefetch the struct (or it's already in cache), the penalty is instead the standard mov.l cycle count of 2 cycles per data unit read [11:19 AM] Moopthehedgehog: Any args not passed in can be used as local variables [11:20 AM] Moopthehedgehog: In general, r0-r7 and fr0-fr7 are considered always clobbered by functions, so unless you are using higher levels of GCC optimization it's use them or lose them [11:20 AM] mrneo240: I've been generally creating the struct then immediately passing by pointer [11:20 AM] Moopthehedgehog: that's fine [11:20 AM] Moopthehedgehog: they're probably cached in that case [11:21 AM] Moopthehedgehog: you only get the 2-cycle penalty the first time they get read from cache into regs</nowiki> == References == 7ec68e80ce53da3f07397782e560e59fa3e6d228 916 915 2020-05-11T19:00:30Z Unknown user 0 /* Register Allocation */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. == Alignment == The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == References == 386a74fb18fc537b41bdfc106e01125c59354a69 917 916 2020-05-11T19:19:38Z Unknown user 0 wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). == References == 50136e36db3e2c8a3ae2b8e12c00f89c823e3c40 918 917 2020-05-11T19:21:46Z Unknown user 0 Reference notation wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches" and SH7750 Software Manual, Section 9 "Instruction Descriptions") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). == References == fd2348d08b5274bd912393b6d984b5c6e6360af6 919 918 2020-05-11T19:21:57Z Unknown user 0 wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A very convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches" and SH7750 Software Manual, Section 9 "Instruction Descriptions") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). == References == 56cfb4d0381f359fcab96dc77762c6c4f5104af7 920 919 2020-05-11T19:24:37Z Unknown user 0 /* Pipelining and Instruction-Level Parallelism */ wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A very convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); Produces this output (GCC 9.2.0): 420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8 But what if it weren't aligned to 4 bytes? Just this: typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; Accessing the data looks like this, in that case (GCC 9.2.0): 555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1 All of this is just from this simple operation: unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches" and SH7750 Software Manual, Section 9 "Instruction Descriptions") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). Appropriate usage of instruction-level parallelism is the only way to achieve >200 MIPS (millions of instructions per second) on a 200MHz SH4. == References == e947911d0caa738ceaa020f9c7efb7b0f0302ac3 GCC-SH4 tips 0 165 921 697 2020-05-11T19:30:49Z Unknown user 0 /* Integer */ wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <pre> mov.l L2,r1 mov.l @r1,r1 </pre> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. (Note: GCC does this conversion automatically, and has done so for at least 10 years now, so you don't need to worry about it) <pre> int result = var1 >> 1; //is the same as var1 / 2 but way faster int result = var1 >> 2; // = var1 / 4 int result = var1 >> 3; // = var1 / 8 </pre> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <pre> float result = var1 * 0.5; // same as / 2 but way faster float result = var1 * 0.25; // same as / 4 but way faster float result = var1 * 0.1; // same as / 10 but way faster </pre> ==References== <references/> f038b8705081c37bcd3ad68b57dca2e65d9c3a0d MIDI adapter 0 30 922 272 2020-05-12T22:23:45Z Unknown user 0 wikitext text/x-wiki The MIDI adapter is a Dreamcast peripheral that connects to the serial port and allows MIDI instrument input and output for use with the Japanese-only title O-to-i-re: Dreamcast Sequencer. internal pictures https://imgur.com/a/IajWMAs {{DCWiki:Stub}} ad1a20c2304f5f0431190fd5385a3b5a09096774 Development 0 2 923 872 2020-05-24T07:44:23Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 0997e58e9cc6110bdf477aee151cb517d7e73966 925 923 2020-05-29T21:54:59Z Unknown user 0 /* Engines */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * Playing SFX * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 20830752ff04b356ffe275930903e04836bcd67a 926 925 2020-05-30T06:17:23Z Unknown user 0 /* Audio */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] d026fb98aed0f81a95ec3843a8f0cf0ddbacc096 Optical drive replacements 0 16 924 864 2020-05-26T18:37:52Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support in menu<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, have to power cycle console with power button || ??? || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} 1f6314e1c46d5c2c2b6a05f33ff5c1c7f53fd2aa Playing SFX 0 277 927 2020-05-30T09:56:53Z Unknown user 0 First commit. Adding example code next wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> 254). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = 4246b0cb55933f8a67ff3de8e2ab0fc385091391 928 927 2020-05-30T10:32:39Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> 254). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> 3ef7b4a378d6ce8a69c939758a26b15e1a372f03 929 928 2020-05-30T10:33:43Z Unknown user 0 Fix formatting wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> 254). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> 3d78d7d2758f1e8e125e5102e37eab6488a2a934 930 929 2020-05-30T10:34:44Z Unknown user 0 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> 254). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> 821fbcb88ac541d1454c02b087caff28739b31fe 931 930 2020-05-30T10:35:30Z Unknown user 0 /* Playing Sound Effects */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> 864547ed3413d438295c9ceb8b7460b5e2f10e81 Playing SFX 0 277 932 931 2020-05-30T10:37:13Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> f4afcc42dedec12830a0865ce2251d8633cb4c2a 933 932 2020-05-30T10:54:46Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Loading Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Playing Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> fea62f64832c9cf362d421d2361e9d386f33ad77 937 933 2020-05-30T11:28:34Z Unknown user 0 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <pre> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </pre> 7cda58fc446c9fc5d35972f201fcff80ed3e5269 941 937 2020-05-30T16:58:42Z Unknown user 0 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] <syntaxhighlight lang="c"> int snd_init() </syntaxhighlight> Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] <syntaxhighlight lang="c"> sfxhnd_t snd_sfx_load(const char* fn) </syntaxhighlight> After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] <syntaxhighlight lang="c"> int snd_sfx_play(sfxhnd_t idx, int vol, int pan) </syntaxhighlight> This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] <syntaxhighlight lang="c"> int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan) </syntaxhighlight> This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] <syntaxhighlight lang="c"> void snd_sfx_stop(int chn) </syntaxhighlight> This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] <syntaxhighlight lang="c"> void snd_sfx_stop_all() </syntaxhighlight> This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] <syntaxhighlight lang="c"> void snd_sfx_unload(sfxhnd_t idx) </syntaxhighlight> This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] <syntaxhighlight lang="c"> void snd_sfx_unload_all() </syntaxhighlight> This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] <syntaxhighlight lang="c"> void snd_shutdown() </syntaxhighlight> Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c"> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 63eddc6595dc226c24f7bd8f71f089ca4e39c396 942 941 2020-05-30T16:59:19Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] <syntaxhighlight lang="c"> int snd_init() </syntaxhighlight> Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] <syntaxhighlight lang="c"> sfxhnd_t snd_sfx_load(const char* fn) </syntaxhighlight> After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] <syntaxhighlight lang="c"> int snd_sfx_play(sfxhnd_t idx, int vol, int pan) </syntaxhighlight> This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] <syntaxhighlight lang="c"> int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan) </syntaxhighlight> This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] <syntaxhighlight lang="c"> void snd_sfx_stop(int chn) </syntaxhighlight> This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] <syntaxhighlight lang="c"> void snd_sfx_stop_all() </syntaxhighlight> This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] <syntaxhighlight lang="c"> void snd_sfx_unload(sfxhnd_t idx) </syntaxhighlight> This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] <syntaxhighlight lang="c"> void snd_sfx_unload_all() </syntaxhighlight> This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] <syntaxhighlight lang="c"> void snd_shutdown() </syntaxhighlight> Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line"> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> c920fbd51151bbfa48d51f3b8e9eabc5f75504a7 943 942 2020-05-30T17:15:39Z Unknown user 0 Highlight API wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] <syntaxhighlight lang="c"> int snd_init() </syntaxhighlight> Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] <syntaxhighlight lang="c"> sfxhnd_t snd_sfx_load(const char* fn) </syntaxhighlight> After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] <syntaxhighlight lang="c"> int snd_sfx_play(sfxhnd_t idx, int vol, int pan) </syntaxhighlight> This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] <syntaxhighlight lang="c"> int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan) </syntaxhighlight> This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] <syntaxhighlight lang="c"> void snd_sfx_stop(int chn) </syntaxhighlight> This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] <syntaxhighlight lang="c"> void snd_sfx_stop_all() </syntaxhighlight> This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] <syntaxhighlight lang="c"> void snd_sfx_unload(sfxhnd_t idx) </syntaxhighlight> This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] <syntaxhighlight lang="c"> void snd_sfx_unload_all() </syntaxhighlight> This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] <syntaxhighlight lang="c"> void snd_shutdown() </syntaxhighlight> Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="18, 21-24, 38, 41, 44, 47, 52, 55, 58, 61, 89-92, 94, 96"> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 8be34c8f35e5405847fdaabcb70cad39fdc9a8bf 945 943 2020-05-30T17:35:33Z Unknown user 0 Added more info to API section to link ref manual and source code wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS reference [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="18, 21-24, 38, 41, 44, 47, 52, 55, 58, 61, 89-92, 94, 96"> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 79b3563477c3ea16527a51802b25a771554e84c4 946 945 2020-05-30T17:36:41Z Unknown user 0 /* API */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="18, 21-24, 38, 41, 44, 47, 52, 55, 58, 61, 89-92, 94, 96"> #include <kos.h> extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, 128); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, 128); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, 255); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, 0); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, 128); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 05a50d521b0302f2f5c69509aa65c958b0daf5c2 948 946 2020-05-30T17:44:21Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="18, 21-24, 38, 41, 44, 47, 52, 55, 58, 61, 89-92, 94, 96"> #include <kos.h> #define LEFT 0 #define MIDDLE 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, MIDDLE); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, MIDDLE); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 96ce7ef498851290179f124dd638c33482ce2f3a 949 948 2020-05-30T17:46:31Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define MIDDLE 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, MIDDLE); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, MIDDLE); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from AICA RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> a1a947bb00a095cc2203c8c8de9753e96315bd1c 950 949 2020-05-30T17:48:37Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on [https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB] '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define MIDDLE 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, MIDDLE); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, MIDDLE); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> a633972d50e5c8d538fa496a11be1ee128821fd5 951 950 2020-05-30T17:49:12Z Unknown user 0 Bold github link wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB]''' '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define MIDDLE 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, MIDDLE); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, MIDDLE); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, MIDDLE); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 10da459bb0d9bc7032460909c7c0bba7069fd760 953 951 2020-05-30T17:52:00Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values. You can also adjust the volume of all the sound effects using the left and right triggers of the controller. You can find can all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB]''' '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 63ee56591ed617276836ab8624c440edcd0295c1 962 953 2020-05-30T18:31:35Z Unknown user 0 Additional comments wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values(LEFT, CENTER, RIGHT). You can also adjust the volume of all the sound effects using the left and right triggers of the controller. Error handling is nonexistent. You want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB]''' '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 70e46146330f5f4845f439998cbf67f12e35ee22 963 962 2020-05-30T18:31:54Z Unknown user 0 /* Code Example */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM. If you want to know how to do that, checkout this guide instead(LINK LATER). = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c here]. == Initializing Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 int '''snd_init'''()] Initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 sfxhnd_t '''snd_sfx_load'''(const char* fn)] After initializing the sound system you can start loading sound effects. This function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f int '''snd_sfx_play'''(sfxhnd_t idx, int vol, int pan)] This function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254'''). 255 will crash your sound system. * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 int '''snd_sfx_play_chn'''(int chn, sfxhnd_t idx, int vol, int pan)] This function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 void '''snd_sfx_stop'''(int chn)] This function stops the specified channel of sound from playing [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e void '''snd_sfx_stop_all'''()] This function stops all channels currently allocated to sound effects from playing == Unload Sound Effects == [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 void '''snd_sfx_unload'''(sfxhnd_t idx)] This function unloads a previously loaded sound effect, and frees the memory associated with it. [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e void '''snd_sfx_unload_all'''()] This function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 void '''snd_shutdown'''()] Shut down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel(using '''snd_sfx_play''') and on the same channel(using '''snd_sfx_play_chn'''). By playing the sound effects on their own channel(pressing A,B,X,Y) you will notice that the sound effects can overlap each other, while playing sound effects on the same channel(with the d-pad) you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values(LEFT, CENTER, RIGHT). You can also adjust the volume of all the sound effects using the left and right triggers of the controller. Error handling is nonexistent in this example. You want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX GITHUB]''' '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> c3165a2e924536b5055dcdcd4e53df4e0bf9bd42 977 963 2020-05-30T20:34:04Z Unknown user 0 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM, but a guide for this will be coming soon. = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found within [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c <code>'''snd_sfxmgr.c'''</code>]. == Initializing Sound System == <syntaxhighlight lang="c">int snd_init()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 <code>'''snd_init()'''</code>] function initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == <syntaxhighlight lang="c">sfxhnd_t snd_sfx_load(const char* fn)</syntaxhighlight> After initializing the sound system you can start loading sound effects. The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 <code>'''snd_sfx_load()'''</code>] function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == <syntaxhighlight lang="c">int snd_sfx_play(sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f <code>'''snd_sfx_play()'''</code>] function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and <s>255</s> '''254''' -- ''255 will crash your sound system in the current KOS version as of this writing''). * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. <syntaxhighlight lang="c">int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 <code>'''snd_sfx_play_chn()'''</code>] function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == <syntaxhighlight lang="c">void snd_sfx_stop(int chn)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 <code>'''snd_sfx_stop()'''</code>] function stops the specified channel of sound from playing. <syntaxhighlight lang="c">void snd_sfx_stop_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e <code>'''snd_sfx_stop_all()'''</code>] function stops all channels currently allocated to sound effects from playing. == Unload Sound Effects == <syntaxhighlight lang="c">void snd_sfx_unload(sfxhnd_t idx)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 <code>'''snd_sfx_unload()'''</code>] function unloads a previously loaded sound effect, and frees the memory associated with it. <syntaxhighlight lang="c">void snd_sfx_unload_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e <code>'''snd_sfx_unload_all()'''</code>] function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == <syntaxhighlight lang="c">void snd_shutdown()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 <code>'''snd_shutdown()'''</code>] function shuts down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel (using <code>'''snd_sfx_play()'''</code>) and on the same channel(using <code>'''snd_sfx_play_chn()'''</code>). By playing the sound effects on their own channel (pressing A,B,X,Y), you will notice that the sound effects can overlap each other; while playing sound effects on the same channel (with the d-pad), you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values (LEFT, CENTER, RIGHT). You can also adjust the volume of all the sound effects using the left and right triggers of the controller. Error handling is non-existent in this example. You'll want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX Github]'''. '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 68fe29de12b2e5c23578ae9b07b22a25d37eb844 Development 0 2 934 926 2020-05-30T11:18:14Z Unknown user 0 /* Debugging & profiling */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[Profiling Simulant applications]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 99ac96f5b49e13d681c779321aaeea437710a95e 935 934 2020-05-30T11:19:18Z Unknown user 0 /* Debugging & profiling */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] d026fb98aed0f81a95ec3843a8f0cf0ddbacc096 936 935 2020-05-30T11:20:17Z Unknown user 0 /* Engines */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * Streaming audio === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 637958eeb918bc814a21aeb7b63135177f1ac235 956 936 2020-05-30T17:57:09Z Unknown user 0 /* Audio */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Linux : BBA with dcload-ip]] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 1b43580b3940e419052886292264c2ee9e9c1c43 980 956 2020-05-30T20:48:14Z Unknown user 0 /* Build & test */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux] (or Windows 10 via Windows Subsystem for Linux)] * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] deea016a2d80e843bd9250439032da3de281084e 981 980 2020-05-30T20:48:28Z Unknown user 0 /* Build & test */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] (or Windows 10 via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 8831a9b17c0b8cf67c38279ba60fc4a4ee383d40 Generate profiling data 0 278 938 2020-05-30T12:16:30Z Unknown user 0 Created page with "== How to enable Simulant's profiler == Every Simulant application allows the user to change various parameters in the AppConfig struct. In order to enable the profiler, the..." wikitext text/x-wiki == How to enable Simulant's profiler == Every Simulant application allows the user to change various parameters in the AppConfig struct. In order to enable the profiler, the following lines should be added to int main() #ifndef NDEBUG config.log_level = smlt::LOG_LEVEL_DEBUG; config.development.force_profiling = true; #endif == How to generate the actual profiling data == Once the user decides to run the application via [[Using dcload-ip with Linux|dcload-ip]], e.g. sudo dc-tool -t 192.168.0.123 -x myCoolGame.elf -c ./assets a file named '''gmon.out''' will be created in '''./build/dreamcast-sh4-gcc/debug/assets''' The file must not be opened while the application is running! During the profiling process the terminal will display how many arcs haven been processed. The output will look like this: -- 1000 arcs recorded... -- 2000 arcs recorded... -- 3000 arcs recorded... Best profiling results can be achieved, if the amount of arcs reaches about 6000 - 7000 entries. '''IMPORTANT:''' To flush the profiling data into '''gmon.out''', the application needs to be properly terminated (e.g. '''ESC''' key). Shutting down the console or terminal prematurely will '''NOT WORK'''. The profiling was successful, if the terminal displays something like this: Stopping profiling... -- Writing 6750 arcs -- Profiler thread finished! c28e8103816aa13653d726c049e7e0ac9baff8b0 939 938 2020-05-30T12:58:54Z Unknown user 0 wikitext text/x-wiki == How to enable Simulant's profiler == Every Simulant application allows the user to change various settings exposed in the AppConfig struct. In order to enable the profiler, the build needs to be run in '''DEBUG''' mode and the following lines should be added to int main() #ifndef NDEBUG config.log_level = smlt::LOG_LEVEL_DEBUG; config.development.force_profiling = true; #endif == How to generate the actual profiling data == Once the user decides to run the application via [[Using dcload-ip with Linux|dcload-ip]], e.g. sudo dc-tool -t 192.168.0.123 -x myCoolGame.elf -c ./assets a file named '''gmon.out''' will be created in '''./build/dreamcast-sh4-gcc/debug/assets''' '''The file must not be opened while the application is running!''' During the profiling process the terminal will display how many arcs haven been processed. The output will look like this: -- 1000 arcs recorded... -- 2000 arcs recorded... -- 3000 arcs recorded... Best profiling results can be achieved, if the amount of arcs reaches about 6000 - 7000 entries. '''IMPORTANT:''' To flush the profiling data into '''gmon.out''', the application needs to be properly terminated (e.g. '''ESC''' key). Shutting down the console or terminal prematurely will '''NOT WORK'''. The profiling was successful, if the terminal displays something like this: Stopping profiling... -- Writing 6750 arcs -- Profiler thread finished! == How to process the profiling data == The file '''gmon.out''' is encoded in a binary file format and needs to be converted into a text file. Copy or move '''gmon.out''' into '''./build/dreamcast-sh4-gcc/debug''' (''debug directory'') If your game is named '''myCoolGame''', you should also find these 2 files in the ''debug directory'': '''myCoolGame.elf''' and '''myCoolGame.elf.debug''' Open the terminal, navigate into the ''debug directory'' and execute the following line: docker run -v `pwd`:`pwd`:Z kazade/dreamcast-sdk /bin/bash -c "source /etc/bash.bashrc; cd `pwd`; sh-elf-gprof myCoolGame.elf.debug gmon.out" > ~/Desktop/gprof.out This will essentially convert the profiling data into a human readable file on your Desktop, which can be viewed with any text editing program. Before moving/reading '''gprof.out''' though, the following line should be executed as a '''final step''': cat ~/Desktop/gprof.out | gprof2dot -n 0.001 | dot -Tsvg -o output.svg A new file named '''output.svg''' will appear in the ''debug directory''. It will visualize the data contained in '''gprof.out''' as a '''graph''', making it easier for the developer to understand relations between different areas of Simulant's engine code. It can be opened with e.g. GIMP or any modern Internet Browser. 93bdd2f88ecc77f3e36cb58e043cb71ff68ea3cc 940 939 2020-05-30T13:01:01Z Unknown user 0 wikitext text/x-wiki == How to enable Simulant's profiler == Every Simulant application allows the user to change various settings exposed in the '''AppConfig''' struct. In order to enable the profiler, the build needs to be run in '''DEBUG''' mode and the following lines should be added to int main() #ifndef NDEBUG config.log_level = smlt::LOG_LEVEL_DEBUG; config.development.force_profiling = true; #endif == How to generate the actual profiling data == Once the user decides to run the application via [[Using dcload-ip with Linux|dcload-ip]], e.g. sudo dc-tool -t 192.168.0.123 -x myCoolGame.elf -c ./assets a file named '''gmon.out''' will be created in '''./build/dreamcast-sh4-gcc/debug/assets''' '''The file must not be opened while the application is running!''' During the profiling process the terminal will display how many arcs haven been processed. The output will look like this: -- 1000 arcs recorded... -- 2000 arcs recorded... -- 3000 arcs recorded... Best profiling results can be achieved, if the amount of arcs reaches about 6000 - 7000 entries. '''IMPORTANT:''' To flush the profiling data into '''gmon.out''', the application needs to be properly terminated (e.g. '''ESC''' key). Shutting down the console or terminal prematurely will '''NOT WORK'''. The profiling was successful, if the terminal displays something like this: Stopping profiling... -- Writing 6750 arcs -- Profiler thread finished! == How to process the profiling data == The file '''gmon.out''' is encoded in a binary file format and needs to be converted into a text file. Copy or move '''gmon.out''' into '''./build/dreamcast-sh4-gcc/debug''' (''debug directory'') If your game is named '''myCoolGame''', you should also find these 2 files in the ''debug directory'': '''myCoolGame.elf''' and '''myCoolGame.elf.debug''' Open the terminal, navigate into the ''debug directory'' and execute the following line: docker run -v `pwd`:`pwd`:Z kazade/dreamcast-sdk /bin/bash -c "source /etc/bash.bashrc; cd `pwd`; sh-elf-gprof myCoolGame.elf.debug gmon.out" > ~/Desktop/gprof.out This will essentially convert the profiling data into a human readable file on your Desktop, which can be viewed with any text editing program. Before moving/reading '''gprof.out''' though, the following line should be executed as a '''final step''': cat ~/Desktop/gprof.out | gprof2dot -n 0.001 | dot -Tsvg -o output.svg A new file named '''output.svg''' will appear in the ''debug directory''. It will visualize the data contained in '''gprof.out''' as a '''graph''', making it easier for the developer to understand relations between different areas of Simulant's engine code. It can be opened with e.g. GIMP or any modern Internet Browser. d6215a713c93e3311053290556c68ab1b22410b9 957 940 2020-05-30T17:57:51Z Unknown user 0 wikitext text/x-wiki == How to enable Simulant's profiler == Every Simulant application allows the user to change various settings exposed in the '''AppConfig''' struct. In order to enable the profiler, the build needs to be run in '''DEBUG''' mode and the following lines should be added to <syntaxhighlight lang="c" inline>int main()</syntaxhighlight>: <syntaxhighlight lang="c">#ifndef NDEBUG config.log_level = smlt::LOG_LEVEL_DEBUG; config.development.force_profiling = true; #endif</syntaxhighlight> == How to generate the actual profiling data == Once the user decides to run the application via [[Using dcload-ip with Linux|dcload-ip]], e.g.: <syntaxhighlight lang="bash">sudo dc-tool -t 192.168.0.123 -x myCoolGame.elf -c ./assets</syntaxhighlight> a file named '''gmon.out''' will be created in '''./build/dreamcast-sh4-gcc/debug/assets''' '''The file must not be opened while the application is running!''' During the profiling process the terminal will display how many arcs haven been processed. The output will look like this: -- 1000 arcs recorded... -- 2000 arcs recorded... -- 3000 arcs recorded... Best profiling results can be achieved, if the amount of arcs reaches about 6000 - 7000 entries. '''IMPORTANT:''' To flush the profiling data into '''gmon.out''', the application needs to be properly terminated (e.g. '''ESC''' key). Shutting down the console or terminal prematurely will '''NOT WORK'''. The profiling was successful, if the terminal displays something like this: Stopping profiling... -- Writing 6750 arcs -- Profiler thread finished! == How to process the profiling data == The file '''gmon.out''' is encoded in a binary file format and needs to be converted into a text file. Copy or move '''gmon.out''' into '''./build/dreamcast-sh4-gcc/debug''' (''debug directory'') If your game is named '''myCoolGame''', you should also find these 2 files in the ''debug directory'': '''myCoolGame.elf''' and '''myCoolGame.elf.debug''' Open the terminal, navigate into the ''debug directory'' and execute the following line: <syntaxhighlight lang="bash">docker run -v `pwd`:`pwd`:Z kazade/dreamcast-sdk /bin/bash -c "source /etc/bash.bashrc; cd `pwd`; sh-elf-gprof myCoolGame.elf.debug gmon.out" > ~/Desktop/gprof.out</syntaxhighlight> This will essentially convert the profiling data into a human readable file on your Desktop, which can be viewed with any text editing program. Before moving/reading '''gprof.out''' though, the following line should be executed as a '''final step''': <syntaxhighlight lang="bash">cat ~/Desktop/gprof.out | gprof2dot -n 0.001 | dot -Tsvg -o output.svg</syntaxhighlight> A new file named '''output.svg''' will appear in the ''debug directory''. It will visualize the data contained in '''gprof.out''' as a '''graph''', making it easier for the developer to understand relations between different areas of Simulant's engine code. It can be opened with e.g. GIMP or any modern Internet Browser. 97562e324db141ebca1a26dbcc0ccbb5374fc329 Building the required toolchains for Sega Dreamcast development 0 261 944 798 2020-05-30T17:16:06Z Unknown user 0 wikitext text/x-wiki In order to produces binaries targetting the Sega Dreamcast hardware, you will need 3 different toolchains: * A ''sh-elf'' toolchain, which will be the main toolchain. It targets the CPU of the Dreamcast, i.e. the Hitachi SH-4 CPU (SuperH). * An ''arm-eabi'' toolchain, which is the toolchain used only for the Yamaha Super Intelligent Sound Processor (AICA). This processor is based on an ARM7 core. It will mainly be used to compile the [[KallistiOS]] sound driver. * The host toolchain from your computer in order to produce some additional tools (i.e. the regular ''gcc'' of your computer). The ''sh-elf'' and ''arm-eabi'' toolchains may be produced by the ''dc-chain'' tool provided with KallistiOS. It's located in the ''utils'' directory. This package contains a ''Makefile'' which both simplifies building the whole Sega Dreamcast toolchain, and gives you substantial control. The dc-chain ''Makefile'' is ready to build everything you need to compile KallistiOS and then develop for the Sega Dreamcast system. == About toolchain components versions == Components that are included in a toolchain are: * '''Binutils''': mainly ld plus other tools; * '''GNU Compiler Collection''' (''gcc''); * '''Newlib''': mainly libc plus other libraries (for ''sh-elf'' only); * '''GNU Debugger''' (''gdb''): (for ''sh-elf'' only). As we are building two toolchains (sh-elf and arm-eabi), all these components will be installed twice, for both targets. Speaking about the best versions to use for the Sega Dreamcast development, they are already declared in the Makefile. This is particulary true for gcc: the best version to use at this time is the 4.7.3. We know that today this version is pretty old but greater versions have serious issues so it's better to stick with that version. Plus, gcc's bugtracker has a lot of bugs marked as [6/7/8/9 Regression] for the sh-elf target which have not been resolved. Newer isn't always better, especially with gcc targets that aren't high-priority. == Advanced options == You may attempt to spawn multiple jobs with make. Using make -j4 is recommended for speeding up the building of the toolchain. There is an option inside the Makefile to set the number of jobs for the building phases. Set the makejobs variable in the Makefile to whatever you would normally feel the need to use on the command line, and it will do the right thing. In the old times, this option may breaks things, so, if you run into trouble, you should clear this variable and try again with just one job running. On MinGW/MSYS environment, it has been confirmed that multiple jobs breaks the toolchain, so please don't try to do that under this environment. This option is disabled by default in this scenario. This doesn't apply to the others environments, including MinGW-w64/MSYS2. == Usage == Before you start, please browse the ./doc directory and check if they are full instructions for building the whole toolchain for your environment. === Making the toolchain === Below you will find some generic instructions: Change the variables in the User Configuration section of the Makefile to match your environment. They can be overridden at the command line as well. Please note, a lot of conditional instructions have been added, so it should work most of the time just out-of-the-box for your environment. Then execute the following for preparing the sources: <syntaxhighlight lang="bash"> ./download.sh ./unpack.sh </syntaxhighlight> Finally, input (for BSD, please use gmake instead): <syntaxhighlight lang="bash"> make </syntaxhighlight> Depending of your environment, this can take a bunch of hours. So please be patient! If anything goes wrong, check the output in logs/. === Making the GNU Debugger (gdb) === For the sh-elf toolchain, if you want to use the GNU Debugger (gdb), you can make it by entering: <syntaxhighlight lang="bash"> make gdb </syntaxhighlight> This will install gdb in the sh-elf toolchain (gdb is used with dcload/dc-tool programs, which are part of KallistiOS too). === Removing all useless files === After the toolchain compilation, you can cleanup everything by entering: <syntaxhighlight lang="bash"> ./cleanup.sh </syntaxhighlight> This will save a lot of space. == Final note == Please see the comments at the top of the Makefile for more build options. d2f2c17fa87aa42dc06d5038155aeedc7109b77a Useful programming tips 0 269 947 920 2020-05-30T17:41:54Z Unknown user 0 wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A very convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: <syntaxhighlight lang="c"> typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; </syntaxhighlight> Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: <syntaxhighlight lang="c"> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </syntaxhighlight> Produces this output (GCC 9.2.0): {| | <syntaxhighlight inline>420 02e4 862F</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l r8,@-r15</syntaxhighlight> |- | <syntaxhighlight inline>421 02e6 4365</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov r4,r5</syntaxhighlight> |- | <syntaxhighlight inline>422 02e8 962F</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l r9,@-r15</syntaxhighlight> |- | <syntaxhighlight inline>423 02ea 0C75</syntaxhighlight> || <syntaxhighlight lang="asm" inline>add #12,r5</syntaxhighlight> |- | <syntaxhighlight inline>424 02ec 224F</syntaxhighlight> || <syntaxhighlight lang="asm" inline>sts.l pr,@-r15</syntaxhighlight> |- | <syntaxhighlight inline>425 02ee 4159</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l @(4,r4),r9</syntaxhighlight> |- | <syntaxhighlight inline>426 02f0 4256</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l @(8,r4),r6</syntaxhighlight> |- | <syntaxhighlight inline>427 02f2 12D0</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l .L71,r0</syntaxhighlight> |- | <syntaxhighlight inline>428 02f4 9869</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r9,r9</syntaxhighlight> |- | <syntaxhighlight inline>429 02f6 6866</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r6,r6</syntaxhighlight> |- | <syntaxhighlight inline>430 02f8 11D4</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l .L72,r4</syntaxhighlight> |- | <syntaxhighlight inline>431 02fa 6966</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.w r6,r6</syntaxhighlight> |- | <syntaxhighlight inline>432 02fc 9969</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.w r9,r9</syntaxhighlight> |- | <syntaxhighlight inline>433 02fe 9869</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r9,r9</syntaxhighlight> |- | <syntaxhighlight inline>434 0300 6868</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r6,r8</syntaxhighlight> |} But what if it weren't aligned to 4 bytes? Just this: <syntaxhighlight lang="c"> typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; </syntaxhighlight> Accessing the data looks like this, in that case (GCC 9.2.0): {| | <syntaxhighlight inline>555 03f0 862F</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l r8,@-r15</syntaxhighlight> |- | <syntaxhighlight inline>556 03f2 4365</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov r4,r5</syntaxhighlight> |- | <syntaxhighlight inline>557 03f4 962F</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l r9,@-r15</syntaxhighlight> |- | <syntaxhighlight inline>558 03f6 0C75</syntaxhighlight> || <syntaxhighlight lang="asm" inline>add #12,r5</syntaxhighlight> |- | <syntaxhighlight inline>559 03f8 224F</syntaxhighlight> || <syntaxhighlight lang="asm" inline>sts.l pr,@-r15</syntaxhighlight> |- | <syntaxhighlight inline>560 03fa 4484</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(4,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>561 03fc 0C63</syntaxhighlight> || <syntaxhighlight lang="asm" inline>extu.b r0,r3</syntaxhighlight> |- | <syntaxhighlight inline>562 03fe 4584</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(5,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>563 0400 0C61</syntaxhighlight> || <syntaxhighlight lang="asm" inline>extu.b r0,r1</syntaxhighlight> |- | <syntaxhighlight inline>564 0402 4684</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(6,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>565 0404 1861</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r1,r1</syntaxhighlight> |- | <syntaxhighlight inline>566 0406 0C60</syntaxhighlight> || <syntaxhighlight lang="asm" inline>extu.b r0,r0</syntaxhighlight> |- | <syntaxhighlight inline>567 0408 3B21</syntaxhighlight> || <syntaxhighlight lang="asm" inline>or r3,r1</syntaxhighlight> |- | <syntaxhighlight inline>568 040a 2840</syntaxhighlight> || <syntaxhighlight lang="asm" inline>shll16 r0</syntaxhighlight> |- | <syntaxhighlight inline>569 040c 0B21</syntaxhighlight> || <syntaxhighlight lang="asm" inline>or r0,r1</syntaxhighlight> |- | <syntaxhighlight inline>570 040e 4784</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(7,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>571 0410 2840</syntaxhighlight> || <syntaxhighlight lang="asm" inline>shll16 r0</syntaxhighlight> |- | <syntaxhighlight inline>572 0412 1840</syntaxhighlight> || <syntaxhighlight lang="asm" inline>shll8 r0</syntaxhighlight> |- | <syntaxhighlight inline>573 0414 1B20</syntaxhighlight> || <syntaxhighlight lang="asm" inline>or r1,r0</syntaxhighlight> |- | <syntaxhighlight inline>574 0416 0869</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r0,r9</syntaxhighlight> |- | <syntaxhighlight inline>575 0418 4884</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(8,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>576 041a 9969</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.w r9,r9</syntaxhighlight> |- | <syntaxhighlight inline>577 041c 0C63</syntaxhighlight> || <syntaxhighlight lang="asm" inline>extu.b r0,r3</syntaxhighlight> |- | <syntaxhighlight inline>578 041e 4984</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(9,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>579 0420 9869</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r9,r9</syntaxhighlight> |- | <syntaxhighlight inline>580 0422 0C62</syntaxhighlight> || <syntaxhighlight lang="asm" inline>extu.b r0,r2</syntaxhighlight> |- | <syntaxhighlight inline>581 0424 4A84</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(10,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>582 0426 2862</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r2,r2</syntaxhighlight> |- | <syntaxhighlight inline>583 0428 0C60</syntaxhighlight> || <syntaxhighlight lang="asm" inline>extu.b r0,r0</syntaxhighlight> |- | <syntaxhighlight inline>584 042a 3B22</syntaxhighlight> || <syntaxhighlight lang="asm" inline>or r3,r2</syntaxhighlight> |- | <syntaxhighlight inline>585 042c 2840</syntaxhighlight> || <syntaxhighlight lang="asm" inline>shll16 r0</syntaxhighlight> |- | <syntaxhighlight inline>586 042e 0B22</syntaxhighlight> || <syntaxhighlight lang="asm" inline>or r0,r2</syntaxhighlight> |- | <syntaxhighlight inline>587 0430 4B84</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.b @(11,r4),r0</syntaxhighlight> |- | <syntaxhighlight inline>588 0432 12D4</syntaxhighlight> || <syntaxhighlight lang="asm" inline>mov.l .L73,r4</syntaxhighlight> |- | <syntaxhighlight inline>589 0434 2840</syntaxhighlight> || <syntaxhighlight lang="asm" inline>shll16 r0</syntaxhighlight> |- | <syntaxhighlight inline>590 0436 1840</syntaxhighlight> || <syntaxhighlight lang="asm" inline>shll8 r0</syntaxhighlight> |- | <syntaxhighlight inline>591 0438 2B20</syntaxhighlight> || <syntaxhighlight lang="asm" inline>or r2,r0</syntaxhighlight> |- | <syntaxhighlight inline>592 043a 0860</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.b r0,r0</syntaxhighlight> |- | <syntaxhighlight inline>593 043c 0961</syntaxhighlight> || <syntaxhighlight lang="asm" inline>swap.w r0,r1</syntaxhighlight> |} All of this is just from this simple operation: <syntaxhighlight lang="c"> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </syntaxhighlight> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: <syntaxhighlight lang="asm"> mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add </syntaxhighlight> (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches" and SH7750 Software Manual, Section 9 "Instruction Descriptions") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). Appropriate usage of instruction-level parallelism is the only way to achieve >200 MIPS (millions of instructions per second) on a 200MHz SH4. == References == a2579765e8ea44b53dc572a11c21205f58a9eb5e 952 947 2020-05-30T17:51:15Z Unknown user 0 wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many programming paradigms that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A very convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: <syntaxhighlight lang="c"> typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; </syntaxhighlight> Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: <syntaxhighlight lang="c"> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </syntaxhighlight> Produces this output (GCC 9.2.0): <syntaxhighlight lang="objdump">420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8</syntaxhighlight> But what if it weren't aligned to 4 bytes? Just this: <syntaxhighlight lang="c"> typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; </syntaxhighlight> Accessing the data looks like this, in that case (GCC 9.2.0): <syntaxhighlight lang="objdump">555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1</syntaxhighlight> All of this is just from this simple operation: <syntaxhighlight lang="c"> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </syntaxhighlight> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: <syntaxhighlight lang="asm"> mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add </syntaxhighlight> (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches" and SH7750 Software Manual, Section 9 "Instruction Descriptions") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). Appropriate usage of instruction-level parallelism is the only way to achieve >200 MIPS (millions of instructions per second) on a 200MHz SH4. == References == 3c6615bdaa28dd3a21fe454a060c2aa67c37c364 MR image 0 73 954 476 2020-05-30T17:52:47Z Unknown user 0 wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size !! Contents |- | 2 bytes || "MR" |- | 4 bytes || Total file size |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Image data offset in bytes (Header size + Palette size) |- | 4 bytes || Image width |- | 4 bytes || Image height |- | 4 bytes || Crap (fill with 0's) |- | 4 bytes || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, input_size): run = 0 length = 0 position = 0 while(position < input_size): run = 1 while((run < 0x17f) and (position+run < input_size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> aae024d3a2aacfa1a66301c9e1a4038d3477bbf2 Texconv 0 155 955 489 2020-05-30T17:54:11Z Unknown user 0 /* Installation */ wikitext text/x-wiki == Description == Texconv is a old but trusty tool to convert .png files into .dtex (some say .dtx) format. '''Source : ''' https://github.com/tvspelsfreak/texconv == Installation == Tested on Linux Mint (2020-01-16) <syntaxhighlight lang="bash"> sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make </syntaxhighlight> 07ad26500dde228cd734c0d6a537e6fdc959e942 GCC-SH4 tips 0 165 958 921 2020-05-30T17:59:58Z Unknown user 0 wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Dan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <syntaxhighlight lang="asm"> mov.l L2,r1 mov.l @r1,r1 </syntaxhighlight> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. (Note: GCC does this conversion automatically, and has done so for at least 10 years now, so you don't need to worry about it) <syntaxhighlight lang="asm"> int result = var1 >> 1; //is the same as var1 / 2 but way faster int result = var1 >> 2; // = var1 / 4 int result = var1 >> 3; // = var1 / 8 </syntaxhighlight> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <syntaxhighlight lang="asm"> float result = var1 * 0.5; // same as / 2 but way faster float result = var1 * 0.25; // same as / 4 but way faster float result = var1 * 0.1; // same as / 10 but way faster </syntaxhighlight> ==References== <references/> 1682353542f805da006b97809d946e0823d519a1 Romdisk Swapping 0 125 959 430 2020-05-30T18:12:56Z Unknown user 0 wikitext text/x-wiki Author: Lerabot/Magnes = Introduction = When I started adding things to the ROM disk, I didn't realize that my 10MB+ .elf file would be problematic (i.e. not load) on the Dreamcast. Also it's been mentioned in a forum topic that loading a romdisk instead of multiple files would be faster. **Need source** I also think that it could be a neat way to handle/manage your memory altogether. ''2020 edit : Removed the GZ compression as it seemed to cause problem with filename longer than a certain length (16 IIRC?)'' = Guide = == Organize your assets == Organize the content or your romdisk in multiple folders: /level1 /level2 /level3 == Convert to romdisk == In your Makefile, duplicate the usual romdisk generation command but change the romdisk name and directory. This is the usual romdisk command, you can still keep this <syntaxhighlight lang="bash">$(KOS_GENROMFS) -f romdisk.img -d path/to/romdisk -v</syntaxhighlight> This is your new romdisk, replace the romdisk_name and romdisk_folder with what you want. <syntaxhighlight lang="bash">$(KOS_GENROMFS) -f romdisk_name.img -d path/to/romdisk_folder -v</syntaxhighlight> If I'm using the example from earlier, I could make a "level1" romdisk this way <syntaxhighlight lang="bash">$(KOS_GENROMFS) -f level1.img -d path/to/level -v</syntaxhighlight> == Using your romdisk == In your code you'll need a way to load those new romdisks, we'll use this code snippet by ''BlackAura''. For more info, check this topic [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=68795&hilit=romdisk+feet+of+fury] <syntaxhighlight lang="c"> #include <kos.h> #include <zlib/zlib.h> // Thanks BlackAura ;) int mount_romdisk(char *filename, char *mountpoint) { void *buffer; int length = zlib_getlength(filename); // Check failure if(length == 0) return 0; // Allocate memory, read file buffer = malloc(length); gzread(file, buffer, length); gzclose(file); // Mount fs_romdisk_mount(mountpoint, buffer, 1); return 1; } </syntaxhighlight> ''' It is important that your mount point start with a '/' -> "/level1" and not "level1" ''' You can now load files that are located at "/level1". Example "/level1/spritesheet.png" You can unload the romdisk using: <syntaxhighlight lang="c">fs_romdisk_unmount(mountpoint);</syntaxhighlight> = Usage with a Broadband adapter or dc-ipload = In order to use these new romdisk, you need to enable ''/pc'' redirection in your ''dc-tool'', update your ''dc-tool'' command to use ''-c'': <syntaxhighlight lang="bash">dc-tool-ip -t dreamcast -c /path/to/project -x program_name.elf</syntaxhighlight> You can now use the function below to access files in the ''/rd'' folder: <syntaxhighlight lang="c">mount_romdisk("/pc/romdisk_name.img", "/rd");</syntaxhighlight> Keep in mind that you'll have to switch ''/pc/'' to ''/cd/'' when you burn this to a CD. ab129000a42932ffb13b8aaaaafdd597cfebef44 Objdump 0 41 960 132 2020-05-30T18:16:05Z Unknown user 0 wikitext text/x-wiki == Random Snippets == * using Objdump to disassemble part of a file, showing how to change the start and stop offsets and also changing from what address we are basing this on <syntaxhighlight lang="bash">sh-elf-objdump -D -b binary -m sh4 -EL --adjust-vma=0x8c008000 --start-address=0x8c00b800 --stop-address=0x8c00b830 IP.BIN</syntaxhighlight> b2fe21c47109ad71984adb89aabce7a51dae370a Galaga 0 259 961 763 2020-05-30T18:31:09Z Unknown user 0 wikitext text/x-wiki ==Description== A port of Galaga made by IMRTechnologies/Ian Micheal. *'''Type''': Shooting Game *'''Website''': Unknown *'''Release Date''': Unknown *'''Download''': [[File:Galaga - SBI version.sbi|thumb|Galaga homebrew game in .sbi format . made by IMRTechnologies]] ==Technical== *Currently only available in .sbi format fadf60279e191085e7d57c305b477e3363d3e586 GLdc 0 24 964 199 2020-05-30T18:33:26Z Unknown user 0 wikitext text/x-wiki [https://github.com/Kazade/GLdc GLdc] is an OpenGL implementation for the Dreamcast that is actively developed by Kazade. MrNeo also contributed to the testing and optimisation of GLdc ==Features== Supports most of the OpenGL 1.2 implementation. ==Known Issue== Lighting performance is still being worked on. ==Projects built with GLdc== *[[Simulant|Simulant engine]] *[[Summoning Signals]] *[[nuQuake]] ==Building GLdc== '''Make sure you clone this repo in the <code>$KOS_BASE/addons</code> folder''' cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git Once the folder is cloned cd GLdc && make defaultall && make create_kos_link You can now link GLdc using <code>-lGLdc</code> 8cbc0ac128af8f9e8e4baadc6705cc3f97714c09 Summoning Signals 0 17 965 63 2020-05-30T18:34:40Z Unknown user 0 wikitext text/x-wiki ==Description== -- insert game description -- *'''Type''': Artgame - Puzzle - ??? *'''Website''': [https://www.patreon.com/12dbsoft](https://www.patreon.com/12dbsoft) [https://magnes.itch.io/summoning-signals](https://magnes.itch.io/summoning-signals) *'''Release Date''': 2020 ==Technical== *2D high resolution sprites using [[GLdc]] *Main engine in C. Game code is in LUA. bbc25d762bf6fac59c54429a315d63cd4b25748f 966 965 2020-05-30T18:34:53Z Unknown user 0 wikitext text/x-wiki ==Description== -- insert game description -- *'''Type''': Artgame - Puzzle - ??? *'''Website''': [https://www.patreon.com/12dbsoft](https://www.patreon.com/12dbsoft) [https://magnes.itch.io/summoning-signals](https://magnes.itch.io/summoning-signals) *'''Release Date''': 2020 ==Technical== *2D high resolution sprites using [[GLdc]] *Main engine in C. Game code is in LUA. 521766c303eebe452d7113b5ed1d9162bca75a9f Hardware Tests 0 150 967 667 2020-05-30T18:36:09Z Unknown user 0 wikitext text/x-wiki Hardware tests serve as living documentation of the Dreamcast hardware. They can be used to verify that behavior matches expectations, or take timing measurements. They can be burnt to a CD and run on retail Dreamcast systems to prove that the test is correct, or they can be used to test clone systems and emulators for correctness. ==Arm7Wrestler DC== *Download: [https://github.com/snickerbockers/dc-arm7wrestler/releases/download/v1/arm7wrestler_dc.tgz] *Source Code: [https://github.com/snickerbockers/dc-arm7wrestler] *Purpose: Tests for CPU bugs in the AICA's ARM7DI. 118601af9836b6dc7d4f22478e91cf69e6264ddd Fast SH4 Vertex Processing 0 84 968 253 2020-05-30T18:45:41Z Unknown user 0 wikitext text/x-wiki [http://yam.20to4.net/dreamcast/hints/index.html Original source] ==Vector Math Instructions== The SH4 CPU featrues some nice builtin math operations. I saw some people trying to speed up their code by using approximations with integer codes and other tricks. That may work but on the SH4 good code that makes use of the builtin instructions will outperform in the most situations. There is not much sense in trying to replace that functions at all since they are already pretty fast. ===<code>FIPR</code>=== Computes the dot product of two 4D vectors <code>x1*x2 + y1*y2 + z1*z2 + w1*w2</code> Often used in lighting formulas. ===<code>FTRV</code>=== Muliplies a 4x4 matrix with a 4D vector Usually used to transform vertices, but can also be used to compute "a * b + c" for four floats in parallel. However, the FMAC may perform better in particular situations because the matrix needs to be setup in a special way. ===<code>FSRRA</code>=== Approximates <code>1.0f / sqrt (x)</code> Usually used to normalize a vector. ===<code>FSCA</code>=== Approximates the sine and cosine. Comes in handy when constructing rotation matrices. This one takes the angle as an integer in the range 0...32767 so it's best to redefine angle representations throughout the whole code so that an angle of PI = 16384 or something. This would save the required conversion (range scale and truncation to integer). ===<code>FSQRT</code>=== Computes <code>sqrt (x)</code> This is actually not a special instruction but it's there and comes in handy sometimes although it's slower than FSRRA so rewrite your math formulas (e.g. range falloff lighting) and try to use FSRRA where applicable instead. ===<code>FMAC</code>=== Computes <code>a * b + c</code> This is as fast as normal float addition, subtraction or multiplication, so basically you pay one and get another operation for free. Comes in handy when doing linear interpolation (polygon clipping, table lookups etc). ===<code>FMOV</code> (64 bit)=== This instruction is very important since it can access the second banked set of the FPU registers that are normally used to hold the vector transformation matrix. It's best to avoid switching the fmov mode very often, so rearrange your data layout. It also requires the data to be 64 bit aligned (8 bytes). ==Cache== The cache is very very important. It is so important that it may either save your day or screw up everything. First of all it is important to understand how the cache works. It is a direct mapped cache, i.e. the cache lines are mapped directly onto the addresses of the memory and since it's only 16 KB small the memory at address (n) is mapped onto the same cache line as the location at address (n + 1024*16) which will result in a cache miss. So it's best to avoid such situations which is not always possible especially when working with large amounts of data, e.g. vertex data. That's where the powerful cache control instructions come in... ===<code>PREF</code>=== Prefetches a cache line for the specified address Use this to prefetch the next element in processing loops for large data buffers. The prefetch delay can be hidden by prefetching the next element at the beginning of the loop. ===<code>OCBWB</code>=== Writes back a cache line This one is often used when cache content and memory content need to be synchronized explicitely for DMA transfers since the DMA controllers operate directly on memory. ===<code>OCBI</code>=== Invalidates a cache line This is also used often with DMA functions before reading a memory area that had just been rewritten by a DMA controller. Another way would be to access the memory area as uncached but this might slow down everything. ===<code>OCBP</code>=== Purges a cache line (write back & invalidate) Use this one after your processing loop definitely has finished its operations for one element. The effect is very similar to the store queues except that you cannot read anything from the store queue lines and can write only 32 or 64 bits at once. ===<code>MOVCA.L</code>=== Allocates a cache line for the specified address This one is very important when processing large buffers. While the OCBP instruction can be left out wihtout any performance drops this is does not apply for MOVCA.L. When processing large buffers you often have an input buffer and an output buffer. The input buffer is read, something is done with the elements and they are stored into the output buffer. Without MOVCA.L a store to the output buffer would cause the cache to read a cache line from the output buffer and redirect the store into the cache. This is a total waste, because most of time every byte of the output buffer is only rewritten with new content. That's what the MOVCA.L is for. It tells the cache to reserve a cache line without fetching memory. But be careful this may cause data corruption. There is another cache feature which makes it possible to use half of the operand cache (i.e. 8 KB) as scratchpad RAM. This may be used to hold transformation loop parameters like matrices or something but it also halves the operand cache size which may decrease overall performance of the code. ==Store Queues== These come in handy when flushing vertices to the graphics hardware or to memory. Basically all they are for is batching up 32 bytes of data and flushing it to some location. The store queues can be used to write to main memory but they bypass the cache thus cache synchronization may become an issue. There are some benefits when using the store queues, among them there are two which I think are worth mentioning. First there are two of them each 32 bytes in size and both operate independently, i.e. you can instruct one store queue to flush its contents and write to the other at the same time without stalling the program code. Then there is another nice feature which I call "data cloning". Sometimes you need to clone data for whatever reason. For one normal store and one cloning operation this implies two reads and two writes per element. With appropriate pointer mapping setup you can reduce this to one read and two writes which will boost the performance of your code. The trick is easy to do. All you have to do is telling a store queue to flush with two different addresses. The store queue number is indicated by bit 6 of the flushing address and the other upper bits are the raw address where the store queue content is flushed to. However, each flush instruction will stall the code until the concerned store queue has finished a previous flush operation. So it's best to do something else between two flush instructions. Notice also that the store queues can be used in conjunction with the MMU for mapping the store queue address space to different pieces of hardware which eliminates the need to set up the QARC0 / QARC1 registers. ==Optimizing TnL Loops== This is probably one of the most frequent optimization topics. Always remember the 20-80 rule: 80 percent of the time is spent in 20 percent of the code. Thus first of all identify your bottle necks. For the most cases this will be the graphics routines, or more precicely the transform and lighting part of the graphics routines, since on Dreamcast this stuff is done by the CPU. When doing "complex" transformation and lighting you may get very large loops that do a lot of operations per vertex. Of course it's best to avoid any operations in the first place (culling) but eventually you will have to compute the lighting intensities for 3 light sources, compute the bumpmapping parameters, apply 8 skinning matrices or whatever you are going to do with one vertex. Let's take a simple example which is supposed to apply diffuse and specular lighting to a vertex, transforming the vertex and storing it in a buffer. This may look as follows: <syntaxhighlight lang="c"> do { fetch vertex apply diffuse lighting ((N * L) * material diffuse color * light color) apply specular lighting (pow ((N * H), material shininess) * material specular color * light color) clamp and pack the lighting result to packed 32 bit ARGB apply transformation (matrix) * (x,y,z,1) apply perspective divide (1/w) write back vertex } while (-- count); </syntaxhighlight> Now add a few more things and you will get quite a big loop and you will run out of FPU registers for sure. Additionally this code is subject to bad pipelining since most of the operatations depend on the results of previous operations. So there are a few things we better do in a different way. Normally each vertex does not depend on adjacent vertices in the buffer. The operations applied are the same for each vertex. If we had a lot of CPU cores as the Cell Processor will we could do some parallel processing, but we don't. Still there is a way to speed things up by processing two vertices at a time, but this will work only if there are enough FPU registers left to hold at least some parts of a second vertex. What we do is simply breaking up the loop in independent and simple steps: *apply diffuse lighting *apply specular lighting *clamp and pack lighting result *apply transformation and perspective divide Thus we'll get something like... <syntaxhighlight lang="c"> do { fetch vertex parts apply diffuse lighting store temporary results } while (-- count); do { fetch vertex parts apply specular lighting store temporary results } while (-- count); do { fetch temporary results clamp and pack lighting result store packed values } while (-- count); do { fetch vertex parts apply transformation apply perspective divide store results } while (-- count); </syntaxhighlight> Now we have small and simple loops that can be pipelined much better since there are more spare registers left. Also the loops can be applied in any order and in any combination making the code more flexible. For instance, if you don't need specular lighting then just don't call the specular lighting loop, that's it. The trick now is to run the small loops not over the whole buffer at once but over smaller blocks of the buffer. This way the currently processed vertices will be kept in the cache for each of the many loop iterations. As to my experience a block size of 32 vertices gives the best performance. Decreasing the value may introduce loop startup or function call overhead. Increasing the value may also increase cache misses. It's the same as with network packet sizes: you have to try a little bit to find the best value. a0ee180f3121be09f66bcffa61aa906560342ab0 Engine & Library 0 27 969 749 2020-05-30T18:50:46Z Unknown user 0 wikitext text/x-wiki This list is an adaptation of the [awesome-dreamcast](https://github.com/dreamcastdevs/awesome-dreamcast) repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[http://elysianshadows.com LibGyro] - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[https://simulant-engine.appspot.com Simulant] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[https://github.com/ianmicheal/Radquakemax radQuake] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[http://elysianshadows.com Elysian Shadows Toolkit] - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] 351d8cde1c68687e081e8e5c6ac26dab7b75b7cf 970 969 2020-05-30T18:51:01Z Unknown user 0 wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[http://elysianshadows.com LibGyro] - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[https://simulant-engine.appspot.com Simulant] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[https://github.com/ianmicheal/Radquakemax radQuake] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[http://elysianshadows.com Elysian Shadows Toolkit] - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] 1d7a93bf16c4d99eba5117f6f11529a0a1cb2d2b Dreamcast emulators 0 4 971 383 2020-05-30T18:57:42Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Other older emulators== These emulators are listed mostly for historical/archival reasons. *[DreamEmu](http://www.dreamemu.net/) *[Dreamer](http://emulatronia.com/dcemu.htm) *Makaron *[Swirly](http://swirly.sourceforge.net/) 7dec5491cac7d854877d6af04053871d72221ee9 Using dcload-ip with Linux 0 37 973 136 2020-05-30T19:10:11Z Unknown user 0 wikitext text/x-wiki ==Linux: using dcload-ip with the BBA== This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, no router in between, using dcload-ip with a hardcoded static IP address. ===Dreamcast side=== Get a selfbooting version of [https://github.com/Moopthehedgehog/dcload-ip dc-load-ip (in the "Releases" section)]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ===Computer side (not necessary if using pre-built DHCP version)=== We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: <syntaxhighlight lang="bash">sudo arp -s [IP address] [MAC address]</syntaxhighlight> *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast *<code>[MAC address]</code> is your dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ===Testing your code=== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight>dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ===Notes (for non-DHCP use)=== ====arp==== The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my <code>environ.sh</code> script. ====Adding a host name==== Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> 7b127dda3df89ad3693d93a30e2d6c5a24e19437 974 973 2020-05-30T19:10:39Z Unknown user 0 wikitext text/x-wiki ==Linux: using dcload-ip with the BBA== This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, no router in between, using dcload-ip with a hardcoded static IP address. ===Dreamcast side=== Get a selfbooting version of [https://github.com/Moopthehedgehog/dcload-ip dc-load-ip (in the "Releases" section)]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA mac address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ===Computer side (not necessary if using pre-built DHCP version)=== We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: <syntaxhighlight lang="bash">sudo arp -s [IP address] [MAC address]</syntaxhighlight> *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast *<code>[MAC address]</code> is your dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ===Testing your code=== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ===Notes (for non-DHCP use)=== ====arp==== The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my <code>environ.sh</code> script. ====Adding a host name==== Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> e0af0c6b4664384e5de9832657b33c9f0be55372 979 974 2020-05-30T20:47:32Z Unknown user 0 wikitext text/x-wiki ==Linux: using dcload-ip with the BBA== This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, with no router in between, using dcload-ip with a hardcoded static IP address. ===Dreamcast side=== Get a selfbooting version of [https://github.com/Moopthehedgehog/dcload-ip dc-load-ip (in the "Releases" section)]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA MAC address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ===Computer side (not necessary if using pre-built DHCP version)=== We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: <syntaxhighlight lang="bash">sudo arp -s [IP address] [MAC address]</syntaxhighlight> *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast *<code>[MAC address]</code> is your dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ===Testing your code=== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ===Notes (for non-DHCP use)=== ====arp==== The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my <code>environ.sh</code> script. ====Adding a host name==== Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> 50517fcd1c74e58c2e9589f6cd0e242320ce8d23 982 979 2020-05-30T20:49:29Z Unknown user 0 wikitext text/x-wiki =Linux: using dcload-ip with the BBA= This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, with no router in between, using dcload-ip with a hardcoded static IP address. ==Dreamcast side== Get a selfbooting version of [https://github.com/Moopthehedgehog/dcload-ip dc-load-ip (in the "Releases" section)]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA MAC address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ==Computer side (not necessary if using pre-built DHCP version)== We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: <syntaxhighlight lang="bash">sudo arp -s [IP address] [MAC address]</syntaxhighlight> *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast *<code>[MAC address]</code> is your dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ==Testing your code== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ==Notes (for non-DHCP use)== ===arp=== The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my <code>environ.sh</code> script. ===Adding a host name=== Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> 29d0015ded273f07c396175711e6e832b17ddd01 Freeware homebrew games 0 76 975 759 2020-05-30T19:19:55Z Unknown user 0 /* Ports */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Space Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[ArmoredCampaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[Clone Keen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[SonicRoboBlast2|Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] dee4764db4440f84bbe830985cbc64063c1c2e25 RADquake 0 279 976 2020-05-30T19:20:43Z Unknown user 0 Created page with " Src code https://github.com/ianmicheal/Radquakemax" wikitext text/x-wiki Src code https://github.com/ianmicheal/Radquakemax 9730a1658b0dddffad4ace4eef2e8e5ce429651a Using dcload-ip with Windows Subsystem for Linux 0 264 983 789 2020-05-30T21:05:48Z Unknown user 0 wikitext text/x-wiki =WSL v2: using dcload-ip with the BBA from WSL and Windows= This tutorial has been tested on Windows 10 and Windows Subsystem for Linux (WSL) v2. My Dreamcast is connected directly to a router that is also connected to my computer, the router is not plugged into anything else, and does not having greater network access, and using dcload-ip with a hardcoded static IP address. ==Dreamcast side== Get a selfbooting version of [https://github.com/Moopthehedgehog/dcload-ip dc-load-ip (in the "Releases" section)]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA MAC address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ==Computer side (not necessary if using pre-built DHCP version)== We'll use the arp function to get your computer to "give" an IP address to your Dreamcast based on its MAC address. ===Under a Windows Terminal=== First we need Administrator access to add an arp entry. <syntaxhighlight lang="powershell">Start-Process PowerShell –Verb RunAs</syntaxhighlight> After you have this PowerShell instance open we will add our entry: <syntaxhighlight lang="powershell">New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "[IP address]" -LinkLayerAddress "[MAC address]"</syntaxhighlight> *If using Wifi, the interface alias is likely <code>"Wi-Fi"</code> This is the command I use: <syntaxhighlight lang="powershell">New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F"</syntaxhighlight> This should be fairly straightword to modify for your needs and network setup. This will be a permanent addition which will persist across restarts and shutdowns. Expected Output: <pre>PS C:\WINDOWS\system32> New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F" ifIndex IPAddress LinkLayerAddress State PolicyStore ------- --------- ---------------- ----- ----------- 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent ActiveStore 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent PersistentStore</pre> ==Notes== *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast. *<code>[MAC address]</code> is your Dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. ==The following can be executed from within Windows or WSL (Linux)== At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ===Testing your code=== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ==Notes (for non-DHCP use)== ===Adding a host name (Linux)=== Also, you can add a line to your host file in order to replace [IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> ===Adding a host name (Windows)=== # Press the Windows key. # Type Notepad in the search field. # In the search results, right-click Notepad and select Run as administrator. # From Notepad, open the following file: <code>c:\Windows\System32\Drivers\etc\hosts</code> # Add a new entry to the file. e.g. <code>dreamcast [IP address]</code> on a newline # Select File > Save to save your changes. You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> 1651f0b432ad4236b655a6570d167c6f6bcb274a Using dcload-ip with Windows Subsystem for Linux 0 264 984 983 2020-05-30T21:07:44Z Unknown user 0 Darc moved page [[Using dcload-ip with WSL]] to [[Using dcload-ip with Windows Subsystem for Linux]] wikitext text/x-wiki =WSL v2: using dcload-ip with the BBA from WSL and Windows= This tutorial has been tested on Windows 10 and Windows Subsystem for Linux (WSL) v2. My Dreamcast is connected directly to a router that is also connected to my computer, the router is not plugged into anything else, and does not having greater network access, and using dcload-ip with a hardcoded static IP address. ==Dreamcast side== Get a selfbooting version of [https://github.com/Moopthehedgehog/dcload-ip dc-load-ip (in the "Releases" section)]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA MAC address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ==Computer side (not necessary if using pre-built DHCP version)== We'll use the arp function to get your computer to "give" an IP address to your Dreamcast based on its MAC address. ===Under a Windows Terminal=== First we need Administrator access to add an arp entry. <syntaxhighlight lang="powershell">Start-Process PowerShell –Verb RunAs</syntaxhighlight> After you have this PowerShell instance open we will add our entry: <syntaxhighlight lang="powershell">New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "[IP address]" -LinkLayerAddress "[MAC address]"</syntaxhighlight> *If using Wifi, the interface alias is likely <code>"Wi-Fi"</code> This is the command I use: <syntaxhighlight lang="powershell">New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F"</syntaxhighlight> This should be fairly straightword to modify for your needs and network setup. This will be a permanent addition which will persist across restarts and shutdowns. Expected Output: <pre>PS C:\WINDOWS\system32> New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F" ifIndex IPAddress LinkLayerAddress State PolicyStore ------- --------- ---------------- ----- ----------- 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent ActiveStore 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent PersistentStore</pre> ==Notes== *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast. *<code>[MAC address]</code> is your Dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. ==The following can be executed from within Windows or WSL (Linux)== At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ===Testing your code=== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ==Notes (for non-DHCP use)== ===Adding a host name (Linux)=== Also, you can add a line to your host file in order to replace [IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> ===Adding a host name (Windows)=== # Press the Windows key. # Type Notepad in the search field. # In the search results, right-click Notepad and select Run as administrator. # From Notepad, open the following file: <code>c:\Windows\System32\Drivers\etc\hosts</code> # Add a new entry to the file. e.g. <code>dreamcast [IP address]</code> on a newline # Select File > Save to save your changes. You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> 1651f0b432ad4236b655a6570d167c6f6bcb274a Using dcload-ip with WSL 0 280 985 2020-05-30T21:07:44Z Unknown user 0 Darc moved page [[Using dcload-ip with WSL]] to [[Using dcload-ip with Windows Subsystem for Linux]] wikitext text/x-wiki #REDIRECT [[Using dcload-ip with Windows Subsystem for Linux]] 7458dfdcb277f51e27b3909dfdcae8d9ea74f33d Development 0 2 986 981 2020-05-30T21:08:37Z Unknown user 0 /* Build & test */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 54a721f05b0a027f66ad22d74b671d58f0d9aaad 1006 986 2020-06-24T06:41:57Z Unknown user 0 /* General */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] c572e3dda123194a149ca1529764a83221e79d66 1007 1006 2020-06-24T18:04:52Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Ready-to-use environments]] ** [[Docker images]] ** [[DreamSDK]] (Windows only) * [[Building the required toolchains for Sega Dreamcast development]] ** [[Building the required toolchains on BSD]] ** [[Building the required toolchains on Cygwin]] ** [[Building the required toolchains on GNU/Linux]] ** [[Building the required toolchains on macOS]] ** [[Building the required toolchains on MinGW/MSYS]] ** [[Building the required toolchains on MinGW-w64/MSYS2]] * [[KallistiOS]] ** [[Building KOS on Linux mint (or Ubuntu)]] ** [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] ** [[Building KOS on macOS]] * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 852f1a258b6cc453493294bd21fa66ac48d0ffb3 1029 1007 2020-09-01T01:50:26Z Unknown user 0 wikitext text/x-wiki === Getting started === ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] a34a1413c74a59a3580a44269079f86fc4ee167b 1030 1029 2020-09-20T22:01:00Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[Special Files]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 4e8455540c209a323eda7e12ef7792abe5308e24 1031 1030 2020-10-10T18:35:56Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 25fc587c2b91ea923998b53adb95f5c20aef9a33 Engine & Library 0 27 987 970 2020-05-30T21:16:09Z Unknown user 0 /* Engine */ wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[http://elysianshadows.com LibGyro] - *(unreleased/in-development)* Cross-platform hardware abstraction layer being developed with Elysian Shadows, supporting Windows, Mac, Linux, PSP, Dreamcast, iOS, Android, OUYA, and more. *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[https://simulant-engine.appspot.com Simulant] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[http://elysianshadows.com Elysian Shadows Toolkit] - *(unreleased/in-development)* General-purpose Toolkit and Engine being actively developed to power Elysian Shadows. Engine and source will be released with the game. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] b8e18bbdaa584ede109e58ef8008de13ffa524f0 RADquake 0 279 988 976 2020-05-30T21:17:23Z Unknown user 0 wikitext text/x-wiki ==Description== A port of Quake made by IMRTechnologies/Ian Micheal. *'''Type''': First-person shooter *'''Source code''': https://github.com/ianmicheal/Radquakemax c6b7dbb8fc7ddb8e91f7bc44fd2689aa88310bfc File:DreamHAL-2020-05-13.zip 6 281 989 2020-05-30T21:52:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=DreamHAL source code}} |date=2020-05-13 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c5006d7f564080ce05b236581569a95619e190c6 DreamHAL 0 282 990 2020-05-30T21:54:50Z Unknown user 0 Created page with "'''DreamHAL''' is a hardware abstraction library for Dreamcast/SH4. * [https://dcemulation.org/phpBB/viewtopic.php?t=105371 DreamHAL announcement post] * [https://dcemulation..." wikitext text/x-wiki '''DreamHAL''' is a hardware abstraction library for Dreamcast/SH4. * [https://dcemulation.org/phpBB/viewtopic.php?t=105371 DreamHAL announcement post] * [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=105441 Dreamcast high-res video modes using DreamHAL] [[:File:DreamHAL-2020-05-13.zip|DreamHAL source code]] 485078f7908cdee3b62acd915ab7d745c24c4b39 991 990 2020-05-30T21:56:26Z Unknown user 0 wikitext text/x-wiki '''DreamHAL''' is a hardware abstraction library for Dreamcast/SH4 written by Moopthehedgehog. * [https://dcemulation.org/phpBB/viewtopic.php?t=105371 DreamHAL announcement post] * [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=105441 Dreamcast high-res video modes using DreamHAL] * Download [[:File:DreamHAL-2020-05-13.zip|DreamHAL source code]] from May 13, 2020 b448404cf168233679b4f51094226d3115cc1805 Playing SFX 0 277 992 977 2020-06-07T07:58:27Z Unknown user 0 Fixed KOS bug wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM, but a guide for this will be coming soon. = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found within [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c <code>'''snd_sfxmgr.c'''</code>]. == Initializing Sound System == <syntaxhighlight lang="c">int snd_init()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 <code>'''snd_init()'''</code>] function initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == <syntaxhighlight lang="c">sfxhnd_t snd_sfx_load(const char* fn)</syntaxhighlight> After initializing the sound system you can start loading sound effects. The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 <code>'''snd_sfx_load()'''</code>] function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == <syntaxhighlight lang="c">int snd_sfx_play(sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f <code>'''snd_sfx_play()'''</code>] function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and 255). * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. <syntaxhighlight lang="c">int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 <code>'''snd_sfx_play_chn()'''</code>] function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == <syntaxhighlight lang="c">void snd_sfx_stop(int chn)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 <code>'''snd_sfx_stop()'''</code>] function stops the specified channel of sound from playing. <syntaxhighlight lang="c">void snd_sfx_stop_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e <code>'''snd_sfx_stop_all()'''</code>] function stops all channels currently allocated to sound effects from playing. == Unload Sound Effects == <syntaxhighlight lang="c">void snd_sfx_unload(sfxhnd_t idx)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 <code>'''snd_sfx_unload()'''</code>] function unloads a previously loaded sound effect, and frees the memory associated with it. <syntaxhighlight lang="c">void snd_sfx_unload_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e <code>'''snd_sfx_unload_all()'''</code>] function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == <syntaxhighlight lang="c">void snd_shutdown()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 <code>'''snd_shutdown()'''</code>] function shuts down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel (using <code>'''snd_sfx_play()'''</code>) and on the same channel(using <code>'''snd_sfx_play_chn()'''</code>). By playing the sound effects on their own channel (pressing A,B,X,Y), you will notice that the sound effects can overlap each other; while playing sound effects on the same channel (with the d-pad), you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values (LEFT, CENTER, RIGHT). You can also adjust the volume of all the sound effects using the left and right triggers of the controller. Error handling is non-existent in this example. You'll want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX Github]'''. '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 23fa3d3e855a039c1bab9240d94630380cc043ae 1018 992 2020-06-28T10:29:42Z Unknown user 0 /* Introduction */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM, look at [[Streaming audio]] instead. = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found within [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c <code>'''snd_sfxmgr.c'''</code>]. == Initializing Sound System == <syntaxhighlight lang="c">int snd_init()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 <code>'''snd_init()'''</code>] function initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == <syntaxhighlight lang="c">sfxhnd_t snd_sfx_load(const char* fn)</syntaxhighlight> After initializing the sound system you can start loading sound effects. The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 <code>'''snd_sfx_load()'''</code>] function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == <syntaxhighlight lang="c">int snd_sfx_play(sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f <code>'''snd_sfx_play()'''</code>] function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and 255). * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. <syntaxhighlight lang="c">int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 <code>'''snd_sfx_play_chn()'''</code>] function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == <syntaxhighlight lang="c">void snd_sfx_stop(int chn)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 <code>'''snd_sfx_stop()'''</code>] function stops the specified channel of sound from playing. <syntaxhighlight lang="c">void snd_sfx_stop_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e <code>'''snd_sfx_stop_all()'''</code>] function stops all channels currently allocated to sound effects from playing. == Unload Sound Effects == <syntaxhighlight lang="c">void snd_sfx_unload(sfxhnd_t idx)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 <code>'''snd_sfx_unload()'''</code>] function unloads a previously loaded sound effect, and frees the memory associated with it. <syntaxhighlight lang="c">void snd_sfx_unload_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e <code>'''snd_sfx_unload_all()'''</code>] function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == <syntaxhighlight lang="c">void snd_shutdown()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 <code>'''snd_shutdown()'''</code>] function shuts down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel (using <code>'''snd_sfx_play()'''</code>) and on the same channel(using <code>'''snd_sfx_play_chn()'''</code>). By playing the sound effects on their own channel (pressing A,B,X,Y), you will notice that the sound effects can overlap each other; while playing sound effects on the same channel (with the d-pad), you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values (LEFT, CENTER, RIGHT). You can also adjust the volume of all the sound effects using the left and right triggers of the controller. Error handling is non-existent in this example. You'll want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX Github]'''. '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 5845eb90ada43cbf1f70d8293ee349bfb0ce0bdb Streaming audio 0 283 993 2020-06-09T12:40:23Z Unknown user 0 Initial draft wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on streaming sound on the Sega Dreamcast. Unlike sound effects, sound that is streamed is '''NOT''' uploaded all-at-once to the Dreamcast AICA RAM. Rather a small buffer of MAX 65536 bytes(per channel) is allocated that we constantly refill while sound is being played. Streamed sound can be either mono or stereo and must be '''16-bit uncompressed PCM''' ('''8-bit PCM''' or '''4-bit Yamaha ADPCM''' is not supported for streaming). The max amount of streams that can exist at once is '''4'''. This hard limit does not apply to sound effects. You can have 4 sound streams playing at once and have many sound effects depending on how much AICA RAM is left. The libraries in [https://github.com/KallistiOS/kos-ports kos-ports] that most people use to stream sound are '''libmp3''', '''libogg''', and '''libtremor'''. These sound libraries take care of all the nitty-gritty stuff covered in the API section. '''So much so that you can skip the API section and go straight to the code example section to get started'''. The approach these sound libraries use to stream sound is to create and run a detached thread in the background that constantly polls the AICA, asking it how much sound data it wants so it can keep streaming. This polling executes a callback where we then decode sound data into a buffer and return that buffer to the AICA to read from. This process continues until we reach the end of the sound file that we are playing. = API = The KOS [http://cadcdev.sourceforge.net/docs/kos-current/stream_8h.html# reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found within [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_stream.c <code>'''snd_stream.c'''</code>]. == Initialize Sound System == <syntaxhighlight lang="c">int snd_stream_init()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a894f8e31f38fcf3d85c6f3ba31f270ce <code>'''snd_stream_init()'''</code>] function initializes the sound system for streaming by allocating some internal stream buffers. It is usually called at the beginning of your program. You can't stream sound before calling this function. This will implicitly call [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 <code>'''snd_init()'''</code>], so you can also play sound effects. == Stream Callback == <syntaxhighlight lang="c">typedef void*(* snd_stream_callback_t)(snd_stream_hnd_t hnd, int smp_req, int *smp_recv)</syntaxhighlight> Functions for providing stream data will be of this type, and can be registered with '''snd_stream_alloc()''' or '''snd_stream_set_callback()'''. * '''hnd''' The stream handle being referred to. * '''smp_req''' The number of samples requested. * '''smp_recv''' Used to return the number of samples available. Returns: A pointer to the buffer of samples. If stereo, the samples should be interleaved. == Allocate Sound Stream == <syntaxhighlight lang="c">snd_stream_hnd_t snd_stream_alloc(snd_stream_callback_t callback, int bufsize)</syntaxhighlight> After initializing the sound system you can start allocating sound streams. The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a8d861495b80a40f14bd09d34d264db55 <code>'''snd_stream_alloc()'''</code>] function allocates a stream and sets its parameters. The maximum number of streams that can be allocated at one time is 4 ([http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ac6a4dd8ba64ce0598beec50ba5c04cca <code>'''SND_STREAM_MAX '''</code>]). This function returns a stream handler that will be used to play/stop streams among other things. * '''callback''' is the function where we decode and send sound data to AICA. * '''bufsize''' is the size of the streaming buffer we want to create in AICA RAM. The maximum size of the buffer we can set is [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a082956718695c49f9bb288db467ef019 <code>'''SND_STREAM_BUFFER_MAX'''</code>] (65536 bytes...per channel so 65536*2 bytes internally to support stereo) . The smaller the buffer size means the sound buffer is filled up faster, which means the sound begins to play quicker. This however means we are decoding many small portions of sound data at a time rather than in bigger chunks. This causes overhead because we are calling the callback function many more times by doing that. I will explain stream queuing which gives us the benefit of both using the max buffer size and having sound playing instantaneously when you start streaming. == Start Stream == <syntaxhighlight lang="c">void snd_stream_start(snd_stream_hnd_t hnd, uint32 freq, int stereo)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a0c0031c395dab0ce8fdc6878ecd9875d <code>'''snd_stream_start()'''</code>] function starts a stream. This function starts processing the given stream, prefilling the buffers as necessary. In queueing mode, this will not start playback. * '''hnd''' The stream to start. * '''freq''' is the frequency of the audio data. Most of the time this is gonna be 44.1Hz. * '''stereo''' is a boolean saying whether the sound data we are streaming is '''1'''-Stereo or '''0'''-Mono == Poll Stream == <syntaxhighlight lang="c">int snd_stream_poll(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a20ac8845b717ca18ddd5dd5a5df676a2 <code>'''snd_stream_poll()'''</code>] function polls the specified stream to load more data if necessary. If more data is requested, the callback function set in [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a8d861495b80a40f14bd09d34d264db55 <code>'''snd_stream_alloc()'''</code>] is executed. * '''hnd''' The stream to poll. == Stop Stream == <syntaxhighlight lang="c"> void snd_stream_stop(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a30aff86794b37e03ae55c2b214962d14 <code>'''snd_stream_stop()'''</code>] function stops a stream, stopping any sound playing from it. This will happen immediately, regardless of whether queueing is enabled or not. * '''hnd''' The stream to stop. == Stream Volume == <syntaxhighlight lang="c">void snd_stream_volume(snd_stream_hnd_t hnd, int vol)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a609a1f999996a6aec8b5f314fe8ad2b5 <code>'''snd_stream_volume()'''</code>] function sets the volume of the specified stream. * '''hnd''' The stream to set volume on. * '''vol''' The volume to set. Valid values are 0-255. == Set Stream Callback == <syntaxhighlight lang="c">void snd_stream_set_callback(snd_stream_hnd_t hnd, snd_stream_callback_t callback)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a895c5ae7c752e1cc0ce3c5d5be17fac3 <code>'''snd_stream_set_callback()'''</code>] function updates the get data callback function for a given stream, overwriting any old callback that may have been in place. * '''hnd''' The stream handle for the callback. * '''callback''' A pointer to the callback function. == Destroy Stream == <syntaxhighlight lang="c">void snd_stream_destroy(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ab53343e65d805c051fad11c5d1c0f887 <code>'''snd_stream_destroy()'''</code>] function destroys a previously created stream, freeing all memory associated with it. * '''hnd''' The stream to clean up. == Shutdown Stream System == <syntaxhighlight lang="c">void snd_stream_shutdown()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a6c818794fe63f75ce0590ba00dec8255 <code>'''snd_stream_shutdown()'''</code>] function shuts down the stream system and frees the memory associated with it. This does not call snd_shutdown(). == Stream Queuing == The stream queuing system allows you to setup a stream to be played, prefilling the buffers, without actually starting the stream. This can be useful if you want to setup a stream long before actually using it. Since the buffers are pre-filled with sound data, playback of the stream is immediate. Normally the route to start playback of a stream is to first allocate a stream using '''snd_stream_alloc()''' and then use '''snd_stream_start()'''. What '''snd_stream_start()''' does internally is that it decodes sound data until the buffer (which you set the size of in '''snd_stream_alloc()''') is full and then sound starts playing. This process isn't instant because decoding the sound data and moving it to the AICA takes time. Normally this is not an issue but if you want to sync the playback of the stream with a button press you will get a delay: <syntaxhighlight lang="c">if(A_BUTTON_IS_PRESSED)) { snd_stream_start(hnd, freq, stereo); }</syntaxhighlight> What you should do instead after allocating a stream using '''snd_stream_alloc()''' is to call '''snd_stream_queue_enable()''' and then '''snd_stream_start()'''. Because we enabled queuing of the stream, the stream will not start playback when we call '''snd_stream_start()'''. It just pre-fills the buffers for us. Then in your control input loop: <syntaxhighlight lang="c">if(A_BUTTON_IS_PRESSED)) { snd_stream_queue_go(hnd); }</syntaxhighlight> === Enable Stream Queue === <syntaxhighlight lang="c">void snd_stream_queue_enable(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#afabae350915f2565c372427f9618e2a7 <code>'''snd_stream_queue_enable()'''</code>] function enables queueing on the specified stream. This will make it so that you must call snd_stream_queue_go() to actually start the stream, after scheduling the start. This is useful for getting something ready but not firing it right away. * '''hnd''' The stream to enable queueing on. === Disable Stream Queue === <syntaxhighlight lang="c">void snd_stream_queue_disable(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a32408db8b9981584904b854192a42aac <code>'''snd_stream_queue_disable()'''</code>] function disables queueing on the specified stream. This does not imply that a previously queued start on the stream will be fired if queueing was enabled before. * '''hnd''' The stream to disable queueing on. === Start Queued Stream === <syntaxhighlight lang="c">void snd_stream_queue_go(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ad639910648dad0c8bf2ec2a2947d445d <code>'''snd_stream_queue_go()'''</code>] function makes the stream start once a start request has been queued, if queueing mode is enabled on the stream. * '''hnd''' The stream to start the queue on. == Stream Filtering == This allows you to apply filters to the decoded sound data that is returned by the callback you set in '''snd_stream_alloc()'''. In order to filter the sound you need to create a function with the filter callback(shown below) and adding it to a stream using '''snd_stream_filter_add()'''. This can create cool dynamic sound manipulation. Manipulating sound data is out of scope of this tutorial and requires you to study DSP(Digital Signal Processing). Keep in mind that you will only be manipulating small portions of sound data at a time. === Filter Callback === <syntaxhighlight lang="c">typedef void(* snd_stream_filter_t)(snd_stream_hnd_t hnd, void *obj, int hz, int channels, void **buffer, int *samplecnt) </syntaxhighlight> Functions providing filters over the stream data will be of this type, and can be set with '''snd_stream_filter_add()'''. * '''hnd''' The stream being referred to. * '''obj''' Filter user data. * '''hz''' The frequency of the sound data. * '''channels''' The number of channels in the sound data. * '''buffer''' A pointer to the buffer to process. This is before any stereo separation is done. Can be changed by the filter, if appropriate. * '''samplecnt''' A pointer to the number of samples/bytes. This can be modified by the filter, if appropriate. === Add Stream Filter === <syntaxhighlight lang="c">void snd_stream_filter_add(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, void* obj)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ab8002470c114f347ea6b9f1e2fe4e299 <code>'''snd_stream_filter_add()'''</code>] function adds a filter to the specified stream. The filter will be called on each block of data input to the stream from then forward. * '''hnd''' The stream to add the filter to. * '''filtfunc''' A pointer to the filter function. * '''obj''' Filter function user data. === Remove Stream Filter === <syntaxhighlight lang="c">void snd_stream_filter_remove(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, void* obj)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a627b9debe59409f085b462f551f17cb8 <code>'''snd_stream_filter_remove()'''</code>] function removes a filter that was previously added to the specified stream. * '''hnd''' The stream to remove the filter from. * '''filtfunc''' A pointer to the filter function to remove. * '''obj''' The filter function's user data. Must be the same as what was passed as obj to '''snd_stream_filter_add()'''. = Code Example = The following code example, which is mostly devoid of the API functions listed above, demonstrates how to stream sound using the libtremor library. The libtremor is a playback library used to play '''.ogg''' sound files. liboggvorbisplay is another library that plays '''.ogg''' files but uses float arithmetic and consumes more memory. Stick with libtremor. I also recommend that you avoid using libmp3 as a playback library if you want to keep your project closed source since its licensed under '''GNU General Public License version 2''' and requires your project to be open source. This code example requires that you have libtremor installed. In your kos-ports directory you will find libtremor. Using your terminal, navigate to that folder and execute: <code>make install clean</code> Error handling is non-existent in this example. You'll want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/Stream/Streaming Github]'''. Three versions of this example exist for each playback library(libtremor, libmp3, and libwav). '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="32, 33, 39, 40, 65, 67, 68,74, 95, 97, 106-108"> #include <kos.h> #include <oggvorbis/sndoggvorbis.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 #define LOOP 1 #define SHAKER_VOL 200 #define INITIAL_CRY 128 #define LOUDEST_CRY 240 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t baby_volume = INITIAL_CRY; uint8_t shake_volume = SHAKER_VOL; uint64_t start_time = timer_ms_gettime64(); uint64_t end_time = start_time; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system and OGG snd_stream_init(); sndoggvorbis_init(); // Load wav files found in romdisk sfxhnd_t shake1 = snd_sfx_load("/rd/shake-1.wav"); sfxhnd_t shake2 = snd_sfx_load("/rd/shake-2.wav"); sndoggvorbis_volume(baby_volume); // Can put volume before starting sndoggvorbis_start("/rd/baby-whining-01.ogg", LOOP); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play rattle sounds to calm the baby if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(shake1, shake_volume, LEFT); if(baby_volume > 40) baby_volume -= 10; } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(shake2, shake_volume, RIGHT); if(baby_volume > 40) baby_volume -= 10; } // Wake the baby if(button_pressed(current_buttons, changed_buttons, CONT_A)) { if(!sndoggvorbis_isplaying()) { baby_volume = INITIAL_CRY; sndoggvorbis_volume(baby_volume); sndoggvorbis_start("/rd/baby-whining-01.ogg", LOOP); } } // Force the baby to sleep if(button_pressed(current_buttons, changed_buttons, CONT_B)) { baby_volume = 0; sndoggvorbis_stop(); } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; // Adjust Volume with time end_time = timer_ms_gettime64(); // Increase baby volume by 15 every second (Max LOUDEST_CRY) if((end_time - start_time) >= 1000) { baby_volume += 15; start_time = end_time; } if(baby_volume > LOUDEST_CRY) { baby_volume = LOUDEST_CRY; } // If baby volume goes <= 40, put baby to sleep if(baby_volume <= 40) { baby_volume = 0; sndoggvorbis_stop(); } else { sndoggvorbis_volume(baby_volume); } draw_instructions(baby_volume); } // Unload all sound effects from sound RAM snd_sfx_unload_all(); sndoggvorbis_stop(); sndoggvorbis_shutdown(); snd_stream_shutdown(); return 0; } static void draw_instructions(uint8_t baby_volume) { int x = 20, y = 20+24; int color = 1; char baby_status[50]; memset(baby_status, 0, 50); if(baby_volume == 0) { snprintf(baby_status, 50, "%-50s", "Baby is asleep!!! Finally..."); } else if(baby_volume > 40 && baby_volume <= 90) { snprintf(baby_status, 50, "%-50s", "Baby is almost asleep. Keep rattling!!"); } else if(baby_volume > 90 && baby_volume <= 180) { snprintf(baby_status, 50, "%-50s", "You can do better than that!"); } else if(baby_volume > 180 && baby_volume <= LOUDEST_CRY) { snprintf(baby_status, 50, "%-50s", "Are you even rattling!?!?!"); } bfont_draw_str(vram_s + y*640+x, 640, color, "Press X and/or Y to play rattle sounds to calm"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "down the baby so it can go to sleep"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press A to wake the baby up"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press B to force baby asleep"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); y += 72; bfont_draw_str(vram_s + y*640+x, 640, color, baby_status); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 759dc964bb0a7429a6b899757e22ae93050b9bad Httpd-ack 0 142 994 651 2020-06-10T22:28:54Z Unknown user 0 wikitext text/x-wiki {{Release |Page name=Httpd-ack |titlescreen=Httpd-ack-1.png |status=Released |releasedby=ackmed (at) gotwalls.com |name=httpd-ack |genre=Tool, Utility |release_date= Jul 11, 2008 |unreleased=No }} {{Download |file=Httpd-ack-20080711.zip }} '''httpd-ack''' is software written for the Dreamcast to dump GD-ROMs via a [[Broadband Adapter]] link. === Usage === * Assign a static IP to your Broadband Adapter using a web browser like [[XDP]] or [[Broadband Passport]]. * Burn the CDI image to a disc and boot the Dreamcast. Alternatively, boot the Dreamcast using [[dcload-ip]] and load the elf file with dc-tool: dc-tool -t <dreamcast ip> -n -x httpd-ack.elf On a PC connected to the same network as the Dreamcast, load a web browser and enter the Dreamcast IP in the URL bar. A menu interface will appear that will allow you to dump tracks from the GD-ROM by clicking a track to "download" it via your browser. By modifying the parameters of the links given to each track, you can manipulate the dumping options: {| class="wikitable" |+Dumping Parameters |- ! Option ! Description |- |track%d |dump track %d (or end sector if >= 100) |- |session%d |dump session %d (or start sector if >= 100) |- |ipbintoc%s |1 = use cdrom TOC thats in IP.BIN for session 2<br />0 = use cdrom's TOC<br />(this option is useful for dumping GD-Rs with swap trick) |- |p%d |unknown param when initializing the cdrom.<br />8192 and 4096 seem to be valid numbers. 8192 for data, 4096 for audio? |- |cdxa%d |something to do with cdxa.<br />0, 1024, 2048 seem to be valid numbers. 1024 for data, 0 for audio? |- |sector_size%d |what sector size to initial the cdrom with for reading.<br />2048 or 2352 are valid. 2352 doesnt always seem to stick and somehow depends on p and cdxa values. |- |gap%d |the end sector for tracks is unknown (except for the last track in a session).<br />so the end sector is calculated by ((start sector of next track - 1) - gap%d). |- |dma%d |1 = use dma when transfering from cdrom<br />0 = use pio |- |sector_read%d |number of sectors to read in each cdrom_read_sectors() call, max 128 |- |sub%d |0 = dont dump sub channel<br />1 = use syscall method to dump sub channel<br />2 = use cdrom_read_sectors method to dump sub channel (dma will be forced to 0, sector_read will be forced to 1) |- |abort%d | 1 = abort on read error<br />0 = continue on read error |- |retry%d |if cdrom_read_sectors() call returns an error, the number of times to retry before giving up |} == Automating dumping == As only one track may be dumped at a time, and the user must sit at the web browser to start dumping the next track, it is recommended to use a script to automate the dumping process if a large number of GD-ROMs will be dumped. A script that can be run on Windows 10, macOS, or Linux is [https://dcemulation.org/dumpcast/viewtopic.php?f=2&t=1666 available]. == GD-R dumping == It is possible to make httpd-ack use the TOC from the IP.BIN at sector 45000 for session 2. The ability to do this is to assist in making it possible to dump GD-R media using a [[Dumping GD-ROMs|swap disc method]], as otherwise the TOC from the old disc would be used when swapping discs with the lid detection switch held down. http://IP/?ipbintoc or http://IP/index.html?ipbintoc The following entry will be logged to the video output to indicate the software is using the TOC from the IP.BIN: get_toc(): using ip.bin for TOC == Dumping a sector range == track%d and session%d have a dual meaning. If both are >= 100, the value of session%d will act as the start sector, and track%d the end sector, and instead of returning an entire track for download, the software will return a file only containing the specific sector range (session%d through track%d). == Screenshots == <gallery mode=nolines heights=168 widths=240> httpd-ack-1.png|Title screen </gallery> == Source == [https://www.gotwalls.com/ gotwalls.com] == Historical builds == *[[:File:Httpd-ack-20080711.zip|httpd-ack 20080711 elf + cdi]] *[[:File:Httpd-ack-20071123.zip|httpd-ack 20071123 elf + cdi]] *[[:File:Httpd-ack-20070720.zip|httpd-ack 20070720 elf + cdi]] *[[:File:Httpd-ack-gdr-test3.zip|httpd-ack gdr-test BETA 3 from 20070626 elf only]] *[[:File:Httpd-ack-gdr-test2.zip|httpd-ack gdr-test BETA 2 from 20070626 elf only]] *[[:File:Httpd-ack-gdr-test.zip|httpd-ack gdr-test BETA 1 from 20070625 elf only]] *[[:File:Httpd-ack-20070624.zip|httpd-ack 20070624 elf only]] *[[:File:Httpd-ack-20070511.zip|httpd-ack 20070511 elf + cdi]] *[[:File:Httpd-ack-20070430.zip|httpd-ack 20070430 elf + cdi]] __NOTOC__ {{DISPLAYTITLE:httpd-ack}} cae6367f60a454668701a4b6d8a64eff9bbc4d5a Optical drive replacements 0 16 995 924 2020-06-13T22:19:28Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with DCDigital mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support<br>Pre-pick swap disc before loading game, and swap using lid open button || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, have to power cycle console with power button || ??? || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} 9c4892f6d4e159b1ca3f251021c3d20aa8c241d8 1005 995 2020-06-23T00:53:14Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-renovation.ru/USB-GDROM_Controller.htm creator's website] || €182, unreleased, ETA late-June or early-July, [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html preorders open]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with [[DCDigital]] mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support<br>Pre-pick swap disc before loading game, and swap using lid open button || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, only possible with [[DCDigital]] mod || No, only possible with [[DCDigital]] mod || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} d1080476eb1844b04bee08431db6eebf3188b614 1026 1005 2020-07-15T16:50:31Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://http://3do-mnemo.com creator's website] || €182, sales through [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html TerraOnion Shop]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with [[DCDigital]] mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support<br>Pre-pick swap disc before loading game, and swap using lid open button || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, only possible with [[DCDigital]] mod || No, only possible with [[DCDigital]] mod || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} b730b77926622eeb84ef66c0d64de457799c827f 1027 1026 2020-07-15T16:51:01Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-mnemo.com creator's website] || €182, sales through [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html TerraOnion Shop]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with [[DCDigital]] mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support<br>Pre-pick swap disc before loading game, and swap using lid open button || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, only possible with [[DCDigital]] mod || No, only possible with [[DCDigital]] mod || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} 55067f4f96240a61ebde0587b2aa5bdc15704a85 1028 1027 2020-07-15T16:51:28Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-mnemo.com/USB-GDROM_Controller.htm creator's website] || €182, sales through [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html TerraOnion Shop]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with [[DCDigital]] mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support<br>Pre-pick swap disc before loading game, and swap using lid open button || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, only possible with [[DCDigital]] mod || No, only possible with [[DCDigital]] mod || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} 5214c835760f22c6c91af2a57dd53e39437b7a81 DCWiki:Hardware 4 82 996 787 2020-06-22T02:47:37Z Unknown user 0 /* Hardware */ wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCDigital]] (formerly DCHDMI), [[S/PDIF]], [[Internal VGA]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]], [[32MB RAM expansion]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} 9d7ee30c202eff2bc197e6e0163a4b79c80ec993 1002 996 2020-06-23T00:44:25Z Unknown user 0 /* Hardware */ wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCDigital]] (formerly DCHDMI), [[S/PDIF]], [[Internal VGA]], [[MIDI expansion|MIDI]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]], [[32MB RAM expansion]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} 251b1c03f774dcc35f32136617468881c06e42ec 32MB RAM expansion 0 284 997 2020-06-22T02:52:25Z Unknown user 0 Created page with "By replacing the Dreamcast's two 8MB SDRAM chips with two 16MB SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to inst..." wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with two 16MB SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information. 8c5a2ca6e25562ee9e03f7c0f5b9d43fe395ee5d 998 997 2020-06-22T19:24:17Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with two 16MB SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. * *'''WARNING'''* THE IMAGES ON THIS DISC ARE EXPERIMENTAL. THE ONLY TESTED 32MB BIOS IS THE jc-v1.032-32MB.bin IMAGE. ** IF YOU FLASH YOUR DC BIOS WITH A 32MB BIOS IMAGE FROM THIS DISC, MAKE SURE YOU HAVE A FUNCTIONING BACKUP BIOS TO RECOVER YOUR DREAMCAST. *** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Read the warning and know what you are doing. **** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. 648a02ba348b671bd466035544676cff98462b3e 999 998 2020-06-22T19:43:53Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with two 16MB SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* THE IMAGES ON THIS DISC ARE EXPERIMENTAL. THE ONLY TESTED 32MB BIOS IS THE jc-v1.032-32MB.bin IMAGE. ** IF YOU FLASH YOUR DC BIOS WITH A 32MB BIOS IMAGE FROM THIS DISC, MAKE SURE YOU HAVE A FUNCTIONING BACKUP BIOS TO RECOVER YOUR DREAMCAST. *** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Read the warning and know what you are doing. **** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. 539fbb25e4b033e10ef166cfcf874f04775d22e3 1000 999 2020-06-22T19:49:54Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* THE IMAGES ON THIS DISC ARE EXPERIMENTAL. THE ONLY TESTED 32MB BIOS IS THE jc-v1.032-32MB.bin IMAGE. ** IF YOU FLASH YOUR DC BIOS WITH A 32MB BIOS IMAGE FROM THIS DISC, MAKE SURE YOU HAVE A FUNCTIONING BACKUP BIOS TO RECOVER YOUR DREAMCAST. *** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Read the warning and know what you are doing. **** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. 1a6a771ea2d9034d7b34bd464f56347789ae619d 1001 1000 2020-06-22T19:50:13Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* THE IMAGES ON THIS DISC ARE EXPERIMENTAL. THE ONLY TESTED 32MB BIOS IS THE jc-v1.032-32MB.bin IMAGE. ** IF YOU FLASH YOUR DC BIOS WITH A 32MB BIOS IMAGE FROM THIS DISC, MAKE SURE YOU HAVE A FUNCTIONING BACKUP BIOS TO RECOVER YOUR DREAMCAST. *** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Read the warning and know what you are doing. **** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. 23a9698b28c953e670c06714cc4b872c5afc2547 1003 1001 2020-06-23T00:45:46Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. At the moment, the only known software able to take advantage of the 32MB RAM expansion is the [https://github.com/tsowell/scummvm-dreamcast/blob/dcalt-backend/backends/platform/dcalt/README.md Alternate ScummVM backend for Dreamcast] by tsowell. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* THE IMAGES ON THIS DISC ARE EXPERIMENTAL. THE ONLY TESTED 32MB BIOS IS THE jc-v1.032-32MB.bin IMAGE. ** IF YOU FLASH YOUR DC BIOS WITH A 32MB BIOS IMAGE FROM THIS DISC, MAKE SURE YOU HAVE A FUNCTIONING BACKUP BIOS TO RECOVER YOUR DREAMCAST. *** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Read the warning and know what you are doing. **** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. 09c648964fc6505ad1fc56563cf16ac9de4325f6 1008 1003 2020-06-25T21:25:19Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. At the moment, the only known software able to take advantage of the 32MB RAM expansion is the [https://github.com/tsowell/scummvm-dreamcast/blob/dcalt-backend/backends/platform/dcalt/README.md Alternate ScummVM backend for Dreamcast] by tsowell. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. {| class="wikitable" style="float:right; margin-left: 10px;" |+32MB-patched BIOS image testing |- |1.004 vanilla |UNTESTED, PROBABLY WORKS |- |1.01c vanilla |UNTESTED, PROBABLY WORKS |- |1.01d vanilla |WORKS |- |1.01d w/ region free patch ("link83") |WORKS |- |1.01d w/ region free patch alt intro ("link83") |WORKS |- |1.01d Treamcast |UNTESTED |- |1.022 ("no mil-CD BIOS") |NOT INCLUDED ON DISC, UNTESTED |- |jc 1.300 regular intro |WORKS |- |jc 1.300 alt intro |UNTESTED, SHOULD WORK |- |jc 1.310 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |jc 1.320 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |dreamboot 1.0.0 |WORKS |- |dreamboot 1.0.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.1 |WORKS |- |dreamboot 1.0.1 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.2 |WORKS |- |dreamboot 1.0.2 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.1.0 |WORKS |- |dreamboot 1.1.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader regular intro |WORKS |- |dreamshell boot loader regular intro No GDROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader alt intro |WORKS |- |dreamshell boot loader alt intro No GD-ROM |WORKS |- |dreamshell sd_loader_with.bios |WORKS |} A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* While most of the BIOS images on the disc have been tested, not all have. See the testing chart to the right. "WORKS" means that the Dreamcast boots up while using this BIOS and boots DreamShell and/or Crazy Taxi. No further testing has been done. ** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! *** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. a3dda0808ccfe7d47962679befd37c13dbde8d2e 1009 1008 2020-06-25T21:52:44Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. At the moment, the only known software able to take advantage of the 32MB RAM expansion is the [https://github.com/tsowell/scummvm-dreamcast/blob/dcalt-backend/backends/platform/dcalt/README.md Alternate ScummVM backend for Dreamcast] by tsowell. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. {| class="wikitable" style="float:right; margin-left: 10px;" |+32MB-patched BIOS image testing |- |1.004 vanilla |UNTESTED, PROBABLY WORKS |- |1.01c vanilla |UNTESTED, PROBABLY WORKS |- |1.01d vanilla |WORKS |- |1.01d w/ region free patch ("link83") |WORKS |- |1.01d w/ region free patch alt intro ("link83") |WORKS |- |1.01d Treamcast |UNTESTED |- |1.022 ("no mil-CD BIOS") |NOT INCLUDED ON DISC, UNTESTED |- |jc 1.300 regular intro |WORKS |- |jc 1.300 alt intro |UNTESTED, SHOULD WORK |- |jc 1.310 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |jc 1.320 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |dreamboot 1.0.0 |WORKS |- |dreamboot 1.0.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.1 |WORKS |- |dreamboot 1.0.1 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.2 |WORKS |- |dreamboot 1.0.2 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.1.0 |WORKS |- |dreamboot 1.1.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader regular intro |WORKS |- |dreamshell boot loader regular intro No GDROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader alt intro |WORKS |- |dreamshell boot loader alt intro No GD-ROM |WORKS |- |dreamshell sd_loader_with.bios |WORKS |} A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* While most of the BIOS images on the disc have been tested, not all have. See the testing chart to the right. "WORKS" means that the Dreamcast boots up while using this BIOS and boots DreamShell and/or Crazy Taxi. There is a high likelihood that some games will exhibit bugs. So far, bugs have been noticed in Sonic Adventure and Phantasy Star Online v2. More testing to come. ** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! *** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. e4cb349ef09f1a76fca696addfcececf7bd535ff 1011 1009 2020-06-26T02:42:02Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. At the moment, the only known software able to take advantage of the 32MB RAM expansion is the [https://github.com/tsowell/scummvm-dreamcast/blob/dcalt-backend/backends/platform/dcalt/README.md Alternate ScummVM backend for Dreamcast] by tsowell. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. {| class="wikitable" style="float:right; margin-left: 10px;" |+32MB-patched BIOS image testing |- |1.004 vanilla |UNTESTED, PROBABLY WORKS |- |1.01c vanilla |UNTESTED, PROBABLY WORKS |- |1.01d vanilla |WORKS |- |1.01d w/ region free patch ("link83") |WORKS |- |1.01d w/ region free patch alt intro ("link83") |WORKS |- |1.01d Treamcast |UNTESTED |- |1.022 ("no mil-CD BIOS") |NOT INCLUDED ON DISC, UNTESTED |- |jc 1.300 regular intro |WORKS |- |jc 1.300 alt intro |UNTESTED, SHOULD WORK |- |jc 1.310 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |jc 1.320 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |dreamboot 1.0.0 |WORKS |- |dreamboot 1.0.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.1 |WORKS |- |dreamboot 1.0.1 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.2 |WORKS |- |dreamboot 1.0.2 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.1.0 |WORKS |- |dreamboot 1.1.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader regular intro |WORKS |- |dreamshell boot loader regular intro No GDROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader alt intro |WORKS |- |dreamshell boot loader alt intro No GD-ROM |WORKS |- |dreamshell sd_loader_with.bios |WORKS |} A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* While most of the BIOS images on the disc have been tested, not all have. See the testing chart to the right. "WORKS" means that the Dreamcast boots up while using this BIOS and boots DreamShell and/or Crazy Taxi. There is a high likelihood that some games will exhibit bugs. So far, bugs have been noticed in Sonic Adventure and Phantasy Star Online v2. More testing to come. ** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! *** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] * A memory testing utility is available as well. [[:File:Memtest.tar.gz]] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. a6637cc293a3036f225ab3bc22316c5dd75beea4 MIDI expansion 0 285 1004 2020-06-23T00:48:59Z Unknown user 0 Created page with "The Dreamcast can interface with MIDI devices using either the serial port based [[MIDI adapter]] or by modifying pins on the expansion port. Pins 49 and 50 represent MIDIOUT..." wikitext text/x-wiki The Dreamcast can interface with MIDI devices using either the serial port based [[MIDI adapter]] or by modifying pins on the expansion port. Pins 49 and 50 represent MIDIOUT and MIDIIN, respectively. 1b653243c4ce548d096572d312b71678bba46836 File:Memtest.tar.gz 6 286 1010 2020-06-26T02:40:59Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{en|1=memtest suite for Dreamcast}} |date=2020-06-25 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f77cd38a9b7c54ea40a4f3dbde938bb38de5b57f Filesystem 0 287 1012 2020-06-28T10:19:04Z Unknown user 0 Created page with "Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any projec..." wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} '''You can find source code that covers this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Adding a Dummy file to push data to outside of disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number says which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> 31bd9d21aacbb628e3e954141420288e5d2ecc72 1013 1012 2020-06-28T10:20:50Z Unknown user 0 /* CD */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} '''You can find source code that covers this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number says which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> 72a2868b32061077adc8c95bd28f0f5afbb58b59 1014 1013 2020-06-28T10:21:58Z Unknown user 0 /* Introduction */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number says which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> 38e9765c80b20932ef0beb1e531b87fdecb54221 1015 1014 2020-06-28T10:22:41Z Unknown user 0 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number says which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' c5f36d5bc7126165ee61871e93b85a6638124ac4 1016 1015 2020-06-28T10:23:00Z Unknown user 0 /* Source Code */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number says which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 82dfd0ea4c85d34dde481d4d814e1e1b25a99e1e 1017 1016 2020-06-28T10:26:47Z Unknown user 0 /* SD card */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number says which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 70be04e99034c43ebbf698827ec45b3523948992 1019 1017 2020-06-28T19:02:59Z Unknown user 0 /* VMU */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [https://dreamcast.wiki/Creating_a_bootable_Dreamcast_disc self bootable CD] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 41f7a45c3835256c90eae61c5eb8e02dc7697b39 1020 1019 2020-06-28T19:20:28Z Unknown user 0 /* CD */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [[Creating a bootable Dreamcast disc|self bootable CD]] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 8ed53f85b14a8a3a740f8977db29bbbe7e3d3fcf 1021 1020 2020-06-28T19:46:20Z Unknown user 0 /* Create */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [[Creating a bootable Dreamcast disc|self bootable CD]] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! Your statically linked romdisk is mounted at '''/rd''' and will stay mounted until the program exits. == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' d3533b2e0bb2008fd51f2985819cdaa0a401bad8 1022 1021 2020-06-28T20:46:02Z Unknown user 0 /* CD */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L112 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [[Creating a bootable Dreamcast disc|self bootable CD]] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/kernel/arch/dreamcast/include/dc/fs_iso9660.h#L36 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! Your statically linked romdisk is mounted at '''/rd''' and will stay mounted until the program exits. == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 3e10ddb90b0c7793aa6555b32706ebb48da67db9 1023 1022 2020-06-28T20:46:43Z Unknown user 0 /* Ramdisk */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L112 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [[Creating a bootable Dreamcast disc|self bootable CD]] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L118 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L35 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! Your statically linked romdisk is mounted at '''/rd''' and will stay mounted until the program exits. == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 553cf3c73731b1b93df3eec6a6fc5ccda1e7b542 1024 1023 2020-06-28T20:47:17Z Unknown user 0 /* Romdisk */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L112 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [[Creating a bootable Dreamcast disc|self bootable CD]] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L118 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L115 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! Your statically linked romdisk is mounted at '''/rd''' and will stay mounted until the program exits. == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 4014bf964eb8d8429ad84047b4619c9fd11cc394 1025 1024 2020-06-28T21:59:30Z Unknown user 0 /* SD card */ wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on KOS's Virtual Filesystem (VFS). It helps to understand KOS's filesystem structure before starting any project. KOS has several mount points: {| class="wikitable" |- ! Dir !! Read !! Write !! Description |- | /cd | style="text-align: center;" | ✔ || || Contains files that exist on the CD that is currently in the Dreamcast. |- | /pc | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || The directory that links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA) |- | /vmu | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains all the VMUs that are currently plugged in. |- | /ram | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || Contains files that have been attached to the ramdisk. |- | /rd | style="text-align: center;" | ✔ || || Contains the contents of the romdisk that was statically linked with the executable. |- | /pty | style="text-align: center;" | NA | style="text-align: center;" | NA || This directory implements a pseudo-terminal filesystem (like Linux's /dev/pty). |- | /sd | style="text-align: center;" | ✔ | style="text-align: center;" | ✔ || This directory appears when you successfully mount the SD card to /sd. |} == Helper Functions == Before we go into more detail about each directory listed in the table above, let's get acquainted with the helper functions that will make your job easier when dealing with KOS's virtual filesystem. <syntaxhighlight lang="c">ssize_t fs_copy(const char *src, const char *dst)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L656 <code>'''fs_copy()'''</code>] function copies the file at src to dst on the filesystem and returns the size of the file. You must be able to write to the dst base directory. You would mainly use this to cache files from /cd to /ram. <syntaxhighlight lang="c">ssize_t fs_load(const char *src, void **out_ptr)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L668 <code>'''fs_load()'''</code>] function opens and reads a whole file into RAM. It returns the size of the data and <code>out_ptr</code> points to the data in RAM. <syntaxhighlight lang="c">ssize_t fs_path_append(char *dst, const char *src, size_t len)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs.h#L690 <code>'''fs_path_append()'''</code>] function acts mostly like the function strncat(), with a few slight differences. When appending a path, this funcion inserts a '/' character if one doesn't already exist between dst and src. It returns the length of the new string (including the NUL terminator). <code>len</code> is the size of the dst buffer. It is used to make sure we stay in bounds of the dst buffer when appending a path. = CD = This directory contains all the files that exist on the CD. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L112 '''8'''] files <u>in /cd</u> '''open''' at one time. One thing to keep in mind when constructing a [[Creating a bootable Dreamcast disc|self bootable CD]] is that the location of a file on the CD affects the reading speeds of that file. This is because the '''GDROM''' in the Dreamcast works in constant angular velocity ('''CAV''') mode. So files that exist on the outer sections of the CD are read faster (12x @ '''~2 MB/sec''') than the inner sections of the CD. Add a dummy file named "0.0" to push data to edge of the disk for faster reads. = PC = This directory links back to your computer if your Dreamcast is somehow linked to your computer (i.e. serial cable, BBA/LA). This directory is available when using DC-Load/DC-Tool combo to upload software to the Sega Dreamcast. By default, '''/pc''' points to the root directory of your computer. Root being: * '''C://''' on Windows * '''Macintosh HD''' on Mac To change the directory '''/pc''' points to, you can use the -c option in DC-Tool like so: <code>dc-tool-ip -t <IP Address> '''-c /path/to/mount/pc''' -x game.elf</code> You must be a '''super user'''. For Windows, ''run as administrator''. For Mac users, use the sudo command (sudo dc-tool-ip -t.. etc). = VMU = This directory contains folders representing VMUs with the '''letternumber''' naming convention. The letter stands for which port the controller that the VMU is plugged into '''(a,b,c, or d)''' and the number stands for which slot the VMU is in '''(1 or 2)'''. {| class="wikitable" style="text-align: center" |- ! scope="col"| ! scope="col"| Port a ! scope="col"| Port b ! scope="col"| Port c ! scope="col"| Port d |- ! scope="row"| Slot 1 | a1 | b1 | c1 | d1 |- ! scope="row"| Slot 2 | a2 | b2 | c2 | d2 |} Inside these folders are game saves, VMU games, etc. Creating/Saving files to the VMU require special file headers that are covered in another tutorial. However, you can easily create a backup of your VMU files using '''fs_copy()''' and saving it to '''/pc''' or '''/sd'''. = Ramdisk = You only have one ramdisk available, and it's mounted on '''/ram'''. This directory is where you can cache many single files from the CD for faster reading access later on. Remember that each file you attach eats up RAM so be sure to detach any files you are not using. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L118 '''8'''] files <u>in /ram</u> '''open''' at one time. There are two functions you can use to "attach" a file to the ramdisk, '''fs_copy()''' and '''fs_ramdisk_attach()''': <syntaxhighlight lang="c">int fs_ramdisk_attach(const char* fn, void* obj, size_t size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L45 <code>'''fs_ramdisk_attach()'''</code>] function takes a block of memory and associates it with a file on the ramdisk. To release or detach a file from the /ram directory you must use '''fs_ramdisk_detach()''': <syntaxhighlight lang="c">int fs_ramdisk_detach(const char* fn, void** obj, size_t* size)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_ramdisk.h#L59 <code>'''fs_ramdisk_detach()'''</code>] function retrieves the block of memory associated with the file, removing it from the ramdisk. You are responsible for freeing obj when you are done with it. Remember to '''fclose()''' any file before you detach it. Examples of each are shown in the code snippets below. == Attach/Detach == <syntaxhighlight lang="c" line="line" highlight="7"> bool attach_file(char* filepath) { void* filedata = NULL; char* filename = basename(filepath); ssize_t filesize = fs_load(filepath, &filedata); if(filesize != -1) { fs_ramdisk_attach(filename, filedata, filesize); return true; } else return false; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="6"> bool attach_file_v2(char* filepath) { char new_path[256] = {0}; char* filename = basename(filepath); fs_path_append(new_path, "/ram", 256); fs_path_append(new_path, filename, 256); ssize_t filesize = fs_copy(filepath, new_path); return filesize > 0; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="5"> void detach_file(char* filename) { void* filedata = NULL; ssize_t filesize = 0; fs_ramdisk_detach(filename, &filedata, &filesize); free(filedata); } </syntaxhighlight> = Romdisk = Romdisk is a small '''read-only''' filesystem. You can think of a romdisk as a single file(or folder) that contains other files. Each romdisk should be organized to contain assets that pertain to a specific level/stage making it easier to know when to load/unload them. You can have a max of [https://github.com/KallistiOS/KallistiOS/blob/298c35ad65c1f52c46352739655160e38d3f5280/include/kos/opts.h#L115 '''16'''] files open across all mounted romdisks at one time. You want to use a romdisk for two reasons: '''1.''' Reading a single file into RAM (from CD) is faster than reading many files because they can be spread out on the CD. Since a romdisk is just a collection of files in a single file, they can be read in one go. You can also gzip the romdisk to make it faster to read from the CD and then ungzip it before you mount it to RAM. I only recommend gzipping your romdisk if it contains uncompressed data files like WAV files, KMG/DTEX(Dreamcast specific images), BMP, etc. '''2.''' Mounting the romdisk into RAM is considered caching the file. Reading from RAM is faster than reading files from the CD. === Create === Creating a romdisk is easy and is usually done inside the makefile with the following command: <syntaxhighlight lang="makefile">$(KOS_GENROMFS) -f <RomdiskFileName> -d <RomdiskFolderPath> -v</syntaxhighlight> You will need to create a folder and fill it with assets for each romdisk you want to create. Then execute the above command for each romdisk specifying a different <RomdiskFileName> and <RomdiskFolderPath>. After creating a romdisk you have two options: '''1. **Recommended** Manually Mount/Unmount Romdisk''' - This approach allows you to mount multiple romdisks at one time at different mountpoints using '''fs_romdisk_mount()'''. Each romdisk you mount eats up RAM so be sure to unmount any romdisks you are not using with '''fs_romdisk_unmount()'''. Remember to '''fclose()''' any files that are open that reference a file that exists in the romdisk you are unmounting. <syntaxhighlight lang="c">int fs_romdisk_mount(const char* mountpoint, const uint8* img, int own_buffer)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L62<code>'''fs_romdisk_mount()'''</code>] function will mount a romdisk image that has been loaded into memory to the specified mountpoint. The mountpoint is the directory name you want to load the romdisks' files from and must be in the format "/directory_name" (e.g. /stage1). This directory is then accessible from the root directory where all other paths (/cd, /ram/, etc) are located. You should pass "1" to <code>own_buffer</code> so that when you unmount the romdisk, the memory you passed in gets freed. <syntaxhighlight lang="c">int fs_romdisk_unmount(const char* mountpoint)</syntaxhighlight> The [https://github.com/KallistiOS/KallistiOS/blob/832ea65b43c8b402f19f3b6b3ecb8804f73c948a/include/kos/fs_romdisk.h#L79 <code>'''fs_romdisk_unmount()'''</code>] function unmounts a romdisk image that has been previously mounted with '''fs_romdisk_mount()'''. If you passed "1" to the own_buffer parameter, then this function will also free the memory. '''- OR -''' '''2. Statically Link Romdisk''' - Makes the romdisk a part of your executable which then automatically gets mounted at '''/rd'''. You can only statically link a single romdisk to your executable. Statically linking a romdisk is discouraged because the romdisk will always stay in RAM which may not be what you want. This approach is mainly used by developers to quickly demo their small programs using DC-Load/DC-Tool without having to enable CDFS redirection. To understand how to statically link a romdisk, lets look at a simple KOS makefile: <div class="toccolours mw-collapsible mw-collapsed"> '''Makefile''' <syntaxhighlight class="mw-collapsible-content" lang="makefile" line highlight="2,13,15-16, 18-19"> TARGET = main.elf OBJS = romdisk.o main.o all: clean $(TARGET) include $(KOS_BASE)/Makefile.rules clean: -rm -f $(TARGET) $(OBJS) -rm -f romdisk.o romdisk.img $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o run: $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) </syntaxhighlight> </div> After a romdisk is created, it is converted to an object file using the following command: <syntaxhighlight lang="makefile">$(KOS_BASE)/utils/bin2o/bin2o <RomdiskFileName> <RomdiskReferenceName> <RomdiskObjFileName></syntaxhighlight> and then the romdisk obj file is added to OBJS: <syntaxhighlight lang="makefile">OBJS = <RomdiskObjFileName> main.o</syntaxhighlight> Now that the romdisk has been statically linked, we have to reference it in your program using the same <RomdiskReferenceName> that was used in the bin2o command. Somewhere above your main function add this: <syntaxhighlight lang="c"> extern uint8 <RomdiskReferenceName>[]; KOS_INIT_ROMDISK(<RomdiskReferenceName>); </syntaxhighlight> and thats it! Your statically linked romdisk is mounted at '''/rd''' and will stay mounted until the program exits. == Mount == <syntaxhighlight lang="c" line="line" highlight="6"> bool mount_romdisk(char* filepath, char* mountpoint) { void *buffer = NULL; ssize_t filesize = fs_load(filepath, &buffer); if(filesize != -1) { fs_romdisk_mount(mountpoint, buffer, 1); return true; } else return false; } </syntaxhighlight> = SD card = If you own a SD card adapter that plugs into the serial port of the Sega Dreamcast, you have the option to mount it on '''/sd''' so you can read/write to it. '''mount_sd_fat()''' below does all the necessary initialization and sets you up to read/write to a '''FAT formatted''' SD card. The function should be called near the beginning of your program. If you do any writing to the SD card, make sure to '''fclose()''' all files on the SD card before calling '''unmount_sd_fat()'''. Otherwise any changes you have made wont be written. In order for you to use these functions you must link with the libkosfat library in your makefile: <syntaxhighlight lang="makefile">kos-cc -o $(TARGET) $(OBJS) $(DATAOBJS) $(OBJEXTRA) -lkosfat</syntaxhighlight> == Mount/Unmount == <syntaxhighlight lang="c" line="line" highlight="5, 11, 16, 21"> bool mount_sd_fat() { kos_blockdev_t sd_dev; uint8 partition_type; if(sd_init()) { printf("Could not initialize the SD card. Please make sure that you " "have an SD card adapter plugged in and an SD card inserted.\n"); return false; } if(fs_fat_init()) { printf("Could not initialize fs_fat!\n"); return false; } if(sd_blockdev_for_partition(0, &sd_dev, &partition_type)) { printf("Could not find the first partition on the SD card!\n"); return false; } if(fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) { printf("Could not mount SD card as fatfs. Please make sure the card " "has been properly formatted.\n"); return false; } return true; } </syntaxhighlight> <syntaxhighlight lang="c" line="line" highlight="2-4"> void unmount_sd_fat() { fs_fat_unmount("/sd"); fs_fat_shutdown(); sd_shutdown(); } </syntaxhighlight> = Source Code = '''You can find source code that covers all this material on [https://github.com/andressbarajas/dreamcastwiki/tree/master/General/Filesystem Github]''' 55c9a301b3919756df1246cef2a64d30eefc5102 MR image 0 73 1032 954 2020-10-14T04:52:27Z Unknown user 0 /* Header */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" |- ! Size (bytes) !! Contents |- | 2 || "MR" |- | 4 || Total file size |- | 4 || Crap (fill with 0's) |- | 4 || Image data offset in bytes (Header size + Palette size) |- | 4 || Image width |- | 4 || Image height |- | 4 || Crap (fill with 0's) |- | 4 || Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, input_size): run = 0 length = 0 position = 0 while(position < input_size): run = 1 while((run < 0x17f) and (position+run < input_size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> 648d7f1d108f2f39474d9b227faf5a73d52dfe5d 1033 1032 2020-10-14T04:54:14Z Unknown user 0 /* Header */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===Header=== {| class="wikitable" style="text-align: center" |- ! Size (bytes) !! Contents |- | 2 |style="text-align: left;"| "MR" |- | 4 |style="text-align: left;"| Total file size |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Image data offset in bytes (Header size + Palette size) |- | 4 |style="text-align: left;"| Image width |- | 4 |style="text-align: left;"| Image height |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, input_size): run = 0 length = 0 position = 0 while(position < input_size): run = 1 while((run < 0x17f) and (position+run < input_size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> 5e12912c5a4a6bca989dd4ef7915e5e67e3031cb MR image 0 73 1034 1033 2020-10-14T04:56:04Z Unknown user 0 /* Header */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===File Header=== {| class="wikitable" style="text-align: center" |- ! Size (bytes) !! Contents |- | 2 |style="text-align: left;"| "MR" |- | 4 |style="text-align: left;"| Total file size |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Image data offset in bytes (Header size + Palette size) |- | 4 |style="text-align: left;"| Image width |- | 4 |style="text-align: left;"| Image height |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, input_size): run = 0 length = 0 position = 0 while(position < input_size): run = 1 while((run < 0x17f) and (position+run < input_size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> 603377db9b2645d9a03551c0b1fcf5ff7e87b55b Emulators on Dreamcast 0 108 1035 403 2020-11-30T10:32:18Z Unknown user 0 wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 3365af276f32d76c549c5cd669f97bca8110c99e 1036 1035 2020-11-30T10:34:16Z Unknown user 0 /* Portable systems */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 0b8389f669f343b18a94aabf56600a1d116b072c 1037 1036 2020-11-30T10:40:02Z Unknown user 0 wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) b605415e8b7ef57e9e45fccb9f217e025acebf0c 1038 1037 2020-11-30T10:44:31Z Unknown user 0 /* Computer systems */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro== *[[BeebemDC]] *[[DreamBBC]] *[[UltraMSX2 DC]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 3e2464cd7758258d1134b3f2e45462262dd8b2c2 1039 1038 2020-11-30T10:44:44Z Unknown user 0 /* =BBC Micro */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[UltraMSX2 DC]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 138fe85847965288fc507d1426d841542625deb8 1040 1039 2020-11-30T10:46:46Z Unknown user 0 /* Portable systems */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[PCSX-DC]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[UltraMSX2 DC]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) d86aeaaf0d2d940dff356b20f206bdb0e7387e71 1042 1040 2020-12-04T12:11:01Z Unknown user 0 /* Video Game systems */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[JaggyDC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[UltraMSX2 DC]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) cb4b352dcd5fbb194ba6bef2f795f41d50bf4fb2 1043 1042 2020-12-04T12:14:12Z Unknown user 0 /* Computer systems */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[JaggyDC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME WIP]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[UltraMSX2 DC]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 84a16d84f3bb992e321e0d8fba514b01ddefce82 1400 1043 2021-04-02T22:44:57Z Unknown user 0 wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[UltraMSX2 DC]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 7028adc9cd0de0908176fc3c3f209a4d5268db1b 1401 1400 2021-04-05T17:17:30Z Unknown user 0 wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega CD/Mega CD=== *[[Heart of the Alien]] *[[ScummVM|The Secret of Monkey Island]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) a1e3851ffeb1b1991e681d84bea1fb3864e0af6f Talk:Useful programming tips 1 288 1041 2020-11-30T15:13:59Z Unknown user 0 Created page with "evt 00e0 implies an unaligned or otherwise illegal read you have to do that if values are forced to be unaligned 00e0 = data or instruction read unaligned 0100 = data write un..." wikitext text/x-wiki evt 00e0 implies an unaligned or otherwise illegal read you have to do that if values are forced to be unaligned 00e0 = data or instruction read unaligned 0100 = data write unaligned they're probably the two most common exceptions you'll get ever. - BlueCrab 10/09/2020 b351b4caec03b943a220016f87983ea6f874fb5f BlueMSX 0 289 1044 2020-12-18T09:56:41Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=BlueMSXDC| image=N/A| homepage=Unknown| version=2.0.2| downloads=| release date=Unknown| author=qamichele59| original=BlueMSX |..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=BlueMSXDC| image=N/A| homepage=Unknown| version=2.0.2| downloads=| release date=Unknown| author=qamichele59| original=BlueMSX | systems=MSX| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: qamichele59 Version: 0.2g Last Updated: no try Description: An Another MSX emulator for your dreamcast. This is one of the greatest ports ever. It comes with full sound and music and its running at FULL SPEED. <br/> Status: There is sound and runs at full speed. =Downloads= No Try [[Category:Emulator]] 11932795ab9c579535706877859f71eff4aad513 Template:Infobox Emulator Information 10 290 1045 2020-12-18T09:57:43Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|<i>No Screenshot Available</i>}}} |- style="background:#ffffff" |Homepage || {{{homepage|<i>Unknown</i>}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|<i>Unknown</i>}}} |- style="background:#ffffff" |Based on || {{{original|<i>Unknown</i>}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|<i>Unknown</i>}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|<i>Unknown</i>}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} 06fe837d287c51b74911d8664ce3f7fe488fdab6 Refresh Rate 0 291 1046 2020-12-18T09:58:08Z Unknown user 0 Created page with "The refresh rate refers to the rate at which a TV redraws data in a second. European countries originally made television sets with a refresh rate measured at 50Hz (also known..." wikitext text/x-wiki The refresh rate refers to the rate at which a TV redraws data in a second. European countries originally made television sets with a refresh rate measured at 50Hz (also known as PAL) and American televisions were featuring 60Hz (also known as NTSC). Now-a-days, European countries are capable of handling 60Hz televisions via new TV sets. 292e180431388c887bfc96c42d38228715971f02 Intellivision MESS Compatibility List 0 663 1423 2021-06-20T17:37:53Z Unknown user 0 Created page with "{| class="wikitable" |- ! Rom title |- | class="ct-broken" | Frogger" wikitext text/x-wiki {| class="wikitable" |- ! Rom title |- | class="ct-broken" | Frogger 7fba3ff63d8011dc4cc02e65443e02474019fb8e 1426 1423 2021-06-20T17:50:59Z Unknown user 0 wikitext text/x-wiki {| class="wikitable" |- ! Rom title ! Controls? ! Playable ! Non-Playable |- | style=background:salmon; | Frogger | No | | Controller Doesn't Load |- | style=background:salmon; |LadyBug | ? | | Controller Glitches |- | style=background:green; |Pac-Man | Yes | Working | |- | style=background:salmon; |Scooby-Doo | - | | Freezes at the opening Title symbol |- | style=background:salmon; |WorldSeriesBaseball | - | | Freezes immediately |} 60cd3357bde1c34cb131fdb1c31a24081f65ed97 1433 1426 2021-06-26T14:14:21Z Unknown user 0 wikitext text/x-wiki {| class="wikitable" |- ! Rom title ! Controls? ! Playable ! Non-Playable |- | style=background:salmon; | Frogger | No | | Controller Doesn't Load |- | style=background:salmon; |LadyBug | ? | | Controller Glitches |- | style=background:salmon; |Pac-Man | - | | Doesn't Work |- | style=background:salmon; |Scooby-Doo | - | | Freezes at the opening Title symbol |- | style=background:salmon; |Space Spartans | Yes | Works without Intellivoice | |- | style=background:salmon; |WorldSeriesBaseball | - | | Freezes immediately |} 5603e2cbf1f5bc33bc988e60dbbdcdc18769a6be 1434 1433 2021-06-26T14:14:40Z Unknown user 0 wikitext text/x-wiki {| class="wikitable" |- ! Rom title ! Controls? ! Playable ! Non-Playable |- | style=background:salmon; | Frogger | No | | Controller Doesn't Load |- | style=background:salmon; |LadyBug | ? | | Controller Glitches |- | style=background:salmon; |Pac-Man | - | | Doesn't Work |- | style=background:salmon; |Scooby-Doo | - | | Freezes at the opening Title symbol |- | style=background:green; |Space Spartans | Yes | Works without Intellivoice | |- | style=background:salmon; |WorldSeriesBaseball | - | | Freezes immediately |} 6c25406cd45426acb3f3143de1ff8f100a4ebc7d Template:No 10 664 1424 2021-06-20T17:39:39Z Unknown user 0 Created page with "<includeonly>style="background:#ff9090; color:black;{{{style|}}}" class="table-no" | {{{1|No}}}</includeonly><noinclude>" wikitext text/x-wiki <includeonly>style="background:#ff9090; color:black;{{{style|}}}" class="table-no" | {{{1|No}}}</includeonly><noinclude> b9e89f1c34bdccabbe3646cb1748d1abb802797e Template:Yes 10 665 1425 2021-06-20T17:40:14Z Unknown user 0 Created page with "<includeonly>style="background:#90ff90; color:black;" class="table-yes" | {{{1|Yes}}}</includeonly><noinclude>" wikitext text/x-wiki <includeonly>style="background:#90ff90; color:black;" class="table-yes" | {{{1|Yes}}}</includeonly><noinclude> 995c2a5a1541ad84dd625bc907dadbe180162ceb GpSPDC Compatibility List 0 666 1427 2021-06-20T18:02:47Z Unknown user 0 Created page with "{| class="wikitable" ! GBA emulator compatibility list for DC by GPF |- ! ROM title ! Region ! style=background:green; | Playable ! style=background:orange; | Partially Playab..." wikitext text/x-wiki {| class="wikitable" ! GBA emulator compatibility list for DC by GPF |- ! ROM title ! Region ! style=background:green; | Playable ! style=background:orange; | Partially Playable ! style=background:salmon; | Non-Playable |- | Classic NES Series.gba | USA | | | Doesn't Work |- | Mario Kart Super Circuit.gba | USA | working | | |- | Mr. Driller 2.gba | USA | Works with no errors | | |- | Oddworld - Munch's Oddysee.gba | USA | working | | |- | PocketNES.gba | USA | | | Non-Working, Major glitched up Compatibility, Graphic issue |- | Rayman Advance - Raving Rabbids.gba | USA | | | Graphic problems |- | Super Mario Avdance 1.gba | USA | working | | |- | Super Mario Advance 2-3.gba | USA | working | | |- | Super Mario Advance 4.gba | USA | | Hangs progress at this Save data is corrupted Error Screen, Requires S-Ram Patch to saving work | |} 8d72a143e6782d5bf78e27992f380f074fa76514 1428 1427 2021-06-20T18:03:12Z Unknown user 0 wikitext text/x-wiki {| class="wikitable" |- ! ROM title ! Region ! style=background:green; | Playable ! style=background:orange; | Partially Playable ! style=background:salmon; | Non-Playable |- | Classic NES Series.gba | USA | | | Doesn't Work |- | Mario Kart Super Circuit.gba | USA | working | | |- | Mr. Driller 2.gba | USA | Works with no errors | | |- | Oddworld - Munch's Oddysee.gba | USA | working | | |- | PocketNES.gba | USA | | | Non-Working, Major glitched up Compatibility, Graphic issue |- | Rayman Advance - Raving Rabbids.gba | USA | | | Graphic problems |- | Super Mario Avdance 1.gba | USA | working | | |- | Super Mario Advance 2-3.gba | USA | working | | |- | Super Mario Advance 4.gba | USA | | Hangs progress at this Save data is corrupted Error Screen, Requires S-Ram Patch to saving work | |} 0bfc1d96efd8b1ca790523da345a49e308c7b4be 1429 1428 2021-06-20T18:11:23Z Unknown user 0 wikitext text/x-wiki {| class="wikitable" |- ! ROM title ! Region ! style=background:green; | Playable ! style=background:orange; | Partially Playable ! style=background:salmon; | Non-Playable |- | Classic NES Series.gba | USA | | | Doesn't Work |- | Mario Kart Super Circuit.gba | USA | working | | |- | Mr. Driller 2.gba | USA | Works with no errors | | |- | Oddworld - Munch's Oddysee.gba | USA | working | | |- | PocketNES.gba | USA | | | Non-Working, Major glitched up Compatibility, Graphic issue |- | Rayman Advance - Raving Rabbids.gba | USA | | | Graphic problems |- | Super Mario Avdance 1.gba | USA | working | | |- | Super Mario Advance 2-3.gba | USA | working | | |- | Super Mario Advance 4.gba | USA | Works (see Partially Playable Notes here) | Hangs progress at this Save data is corrupted Error Screen, Requires S-Ram Patch to saving work | |} b986ed78fa7130ed2f5674d457efc0050e712325 MIDI adapter 0 30 1439 922 2021-07-06T23:00:37Z Unknown user 0 wikitext text/x-wiki The MIDI adapter is a Dreamcast peripheral that connects to the serial port and allows MIDI instrument input and output for use with the Japanese-only title O-to-i-re: Dreamcast Sequencer. internal pictures https://imgur.com/a/IajWMAs A clone version has been created by Ben Ryves with [http://benryves.com/journal/3763164 instructions to DIY on his journal]. {{DCWiki:Stub}} 656b0ace65c438f7b4c2426cd080b9883960940a Check-GD 0 257 1442 866 2021-07-08T15:40:34Z Unknown user 0 wikitext text/x-wiki There were several '''Check-GD''' discs (also known as '''DC Checker''') created for the Dreamcast. Some discs are just later builds of earlier disc's software, or variant versions of the software intended for different use cases. =Known pressed & labelled GD-ROMs= *'''SDPS-1''': Loop Checker / 1.00 / SEGA CS / 01/06/2000 ('''<span style="color:green">dumped</span>''') *'''SDPS-2''': Unknown ('''<span style="color:red">undumped</span>''') *'''SDPS-3''': DC checker for REPAIR / 2.15R / CS.R&D / 01/12/2000 ('''<span style="color:green">dumped</span>''') *'''SDPS-4''': DC checker for MP / 2.16M / CS / 02/02/2000 ('''<span style="color:green">dumped</span>''') *'''SDPS-5''': DC checker for REPAIR / 2.16R / CS / 02/02/2000 ('''<span style="color:red">undumped</span>''') *'''SDPS-6''': Unknown ('''<span style="color:red">undumped</span>''') *'''SDPS-7''': Himozuke Family / 2.40 / CS / 07/14/2000 ('''<span style="color:red">undumped</span>''') *Internal Printing Disc (HKT-999999) - ('''<span style="color:red">undumped</span>''') No images available, believed to be the same software as GD Drive Repair Program silver disc? =Known pressed silvers= *DC Checker for Repair v2.05R (DCSC205R) ('''<span style="color:green">dumped</span>''') (10/27/1999 date in IP.BIN) *GD Drive Repair Program 0.1 (DCGD01) ('''<span style="color:green">dumped</span>''') (12/01/1998 date in IP.BIN) ==Hidden options== There are multiple modes that the disc can be run in depending on what buttons you hold down at the IP.BIN screen: *Holding nothing: Full checker *Holding A + B: Full checker but without modem checks, req. for Asian modemless consoles to pass *Holding X + Down on D-Pad: MP Checker mode, skips critical tests but runs the other tests *Holding X + Right on D-Pad: Single test mode, disables test script and allows you to scroll through the individual tests and pick them at will *Holding Y + Up on D-Pad: CLX Signature check, which renders a scene and compares calculated graphics data against reference data *Holding Y + Right: CLX Signature Aging test, which performs the above test repeatedly on a loop. This test is available with and without a GD drive seek test included in the test loop. *Holding Y + Down on D-Pad: Sonic Cube mode, which allows you to run several Holly samples, basically the same ones that are run during the scripted test modes, but you can control them with controller. **Non-Tex Cube **Tex Cube **Punch-Thru Cube (X+Up/Down increases/decreases number of cubes, Y+Up/Down zooms in and out, start pauses/resumes motion) **Vertex Test (B toggles mirror map and transparency, d-pad moves screen) **Torus test (A changes number of doughnuts, Y+Up/Down zooms in/out, start pauses/resumes motion) *Holding X + Left: FlashROM viewer mode, which displays information about the console stored in the FlashROM (serial number, factory codes, etc.) *Holding X + Up: Katana Set5 checker mode, which runs the same diagnostic tests as those built into the BIOS of the Katana Set5 *Holding A + B + X + Down: Address checker mode, which displays a blank screen but allows the user to control a "tiny address checker" program via serial link ==Console bricking risk== During the test process, the console flashROM is subject to both read and write tests, which result in the flashROM being completely erased (along with all console settings, ISP settings, [[Phantasy Star Online]] serial number & access code, etc.). This will not cause issues on a stock console, however, if the console has been modified with the [[region change]] mod and the write-enable wire has not been removed, the console's region coding will be erased and the console will no longer boot any software unless the flashROM is repaired or a region-free BIOS is installed. 6b7482048cd0ae50efee0ad8b1c42c0591f1adec User talk:Freakdave 3 692 1461 2022-07-26T12:45:41Z Unknown user 0 TEST wikitext text/x-wiki TEST 984816fd329622876e14907634264e6f332e9fb3 1462 1461 2022-07-26T12:48:13Z Unknown user 0 Blanked the page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Twiddle.png 6 693 1463 2022-08-06T11:55:45Z Unknown user 0 wikitext text/x-wiki Original pixel's indexes on twiddled image e3425d49c45eb5d4368058b9c7c152f6788b8757 User:Freakdave 2 133 1464 402 2022-11-09T22:11:15Z Unknown user 0 /* Current projects */ wikitext text/x-wiki === Past projects === * Extended [http://surreal64ce.wikidot.com/info:info Surreal64] (N64 emulator on XBOX) * Ported [https://www.emuxtras.net/forum/viewtopic.php?f=189&t=3543 Yabause CE] (Sega Saturn emulator) to XBOX * Ported countless open-source [https://web.archive.org/web/20121014020252/http://freakdave.xbox-scene.com/ SDL games] (e.g. Zelda - Oni Link Begins, Jump 'n' BumpX, etc..) to XBOX * Created Project Dash ([https://xbins.org/nfo.php?file=xboxnfo2181.nfo GUI frontend used in Yabause CE and partly 3dox]) * Ported [http://svn.huntsvegas.org/listing.php?repname=FakeGLx FakeGLx] and [http://svn.huntsvegas.org/listing.php?repname=xGLDirect xGLDirect] (Direct3D -> OpenGL wrapper) to XBOX * Ported [http://svn.huntsvegas.org/listing.php?repname=IrrlichtX IrrlichtX] (graphics engine) to XBOX * Contributed various speed up fixes to the XBOX port of the Playstation 1 emulator [https://github.com/freakdave/PCSX-ReloadedX-Stable PCSX-ReloadedX] === Current projects === * Create a small 3D homebrew demo for the Dreamcast with [[Simulant]] * Contribute code and bug fixes to [[Simulant]] * Work with kazade on Driving Strikers [[Simulant]] 0343ca1d4e715be024bec9c6f8e44ce46a7d5c09 Getting Started with Dreamcast development 0 694 1467 2022-12-08T18:44:08Z Unknown user 0 Created page with "''BEWARE: THIS ARTICLE IS CURRENTLY A WIP'' =Introduction= Explain the basic ideas behind the toolchain, KOS, KOS-ports, and a debug link. This guide will cover: * Steps req..." wikitext text/x-wiki ''BEWARE: THIS ARTICLE IS CURRENTLY A WIP'' =Introduction= Explain the basic ideas behind the toolchain, KOS, KOS-ports, and a debug link. This guide will cover: * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to offer assistance and update the guide for the benefit of future readers and others in the community. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) sudo mkdir -p -m 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options ./download.sh ./unpack.sh make erase=1 Toolchain is now built. =Configuring and compiling KOS and kos-ports= cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following whenever developing: source /opt/toolchains/dc/kos/environ.sh cd /opt/toolchains/dc/kos make KOS is now built. git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. e94a10b0b1e61fbf800924a25106f8a7d17d3133 1468 1467 2022-12-08T18:46:35Z Unknown user 0 wikitext text/x-wiki ''BEWARE: THIS ARTICLE IS CURRENTLY A WIP'' =Introduction= Explain the basic ideas behind the toolchain, KOS, KOS-ports, and a debug link. This guide will cover: * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to offer assistance and update the guide for the benefit of future readers and others in the community. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) sudo mkdir -p -m 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options ./download.sh ./unpack.sh make erase=1 Toolchain is now built. =Configuring and compiling KOS and kos-ports= cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following whenever developing: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. 4b02b5a812912550d6524147528612ce3c28518f 1469 1468 2022-12-08T18:54:51Z Unknown user 0 wikitext text/x-wiki ''BEWARE: THIS ARTICLE IS CURRENTLY A WIP'' =Introduction= Explain the basic ideas behind the toolchain, KOS, KOS-ports, and a debug link. This guide will cover: * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to offer assistance and update the guide for the benefit of future readers and others in the community. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make erase=1 Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. d2cb935739bfb7473bf15ad6bfae784876a47a38 1470 1469 2022-12-08T19:11:10Z Unknown user 0 wikitext text/x-wiki ''BEWARE: THIS ARTICLE IS CURRENTLY A WIP'' =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. Explain the basic ideas behind the toolchain, KOS, KOS-ports, and a debug link. This guide will cover: * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to offer assistance and update the guide for the benefit of future readers and others in the community. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make erase=1 Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. acf3de68849125cae3b67f9e5fc5f0b8b6e22889 1471 1470 2022-12-08T19:18:35Z Unknown user 0 wikitext text/x-wiki ''BEWARE: THIS ARTICLE IS CURRENTLY A WIP'' =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. Explain the basic ideas behind the toolchain, KOS, KOS-ports, and a debug link. This guide will cover: * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to offer assistance and update the guide for the benefit of future readers and others in the community. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 8a8895324b13eae13724bf66b0cf475a8c4cdf38 1472 1471 2022-12-08T19:45:20Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. There are others in existence, like [[libronin]] and [[libdream]], as well as the commercially used [[Katana]] and [[Windows CE]], but this guide will only cover the setup and use of KallistiOS. Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 95562d61dbce076dae0c191e38da5015f3d5381f 1473 1472 2022-12-08T20:11:24Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems * Debian- and Ubuntu-based Linux distributions * Fedora-based Linux distributions ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. There are others in existence, like [[libronin]] and [[libdream]], as well as the commercially used [[Katana]] and [[Windows CE]], but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's [[Broadband adapter]] and [[LAN adapter]] accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. d2db5f25cb0fd7a9ff3ae168626fd9fb3a0bee0b 1478 1473 2022-12-08T20:26:31Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems * Debian- and Ubuntu-based Linux distributions * Fedora-based Linux distributions ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's [[Broadband adapter]] and [[LAN adapter]] accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. f8152883c026789fbb38d35c504eb97af09c50f8 1479 1478 2022-12-08T20:39:28Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems * Debian- and Ubuntu-based Linux distributions * Fedora-based Linux distributions ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. b5f0f6375299b4d69752251efe5a67b25299337f 1480 1479 2022-12-08T21:04:27Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 079967f66ea50ac20a7e6f7c745939245a01d43b 1481 1480 2022-12-08T23:36:19Z Unknown user 0 /* Choosing a debug link solution */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Copy the pre-made environment script into place: cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: cd /opt/toolchains/dc/kos make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 7004b6a720d8424e9d31e17c4a48b8c3e06f58ad 1482 1481 2022-12-09T01:26:24Z Unknown user 0 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh Edit the environ.sh to your liking. Run the following in your terminal whenever working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 4de45621aaf59920f7c118d2cd470eb19ce94db5 1483 1482 2022-12-09T01:58:17Z Unknown user 0 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= First, install dependencies (e.g. gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev) using your system's package manager. Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 1cd45bebf01065df34b02a9d49d7ea473a63da2f 1484 1483 2022-12-09T04:47:10Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ==Dependencies== ===Debian/Ubuntu-based Linux=== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ===Other distributions=== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain Choose one of the following pre-made toolchain configurations: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 62d35e44afa79624d8e5cda1efe9951fcc46a4aa 1485 1484 2022-12-09T04:54:40Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ==Dependencies== ===Debian/Ubuntu-based Linux=== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ===Other distributions=== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 7d8b4e0895d4ca522f6d1f4a9dc7f3fe3577a3ad 1486 1485 2022-12-09T05:07:52Z Unknown user 0 wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== ====Debian/Ubuntu-based Linux==== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 2fbd46ee43e407adac20932e2a1aef8a2d6e4376 Efficient usage of the Dreamcast RAM 0 695 1474 2022-12-08T20:12:44Z Unknown user 0 Created page with "Written by bogglez = Introduction = SDRAMs are essentially DRAMs on steroids, with a minor interface on top of them that allows some degree of pipelining. SDRAMs are designe..." wikitext text/x-wiki Written by bogglez = Introduction = SDRAMs are essentially DRAMs on steroids, with a minor interface on top of them that allows some degree of pipelining. SDRAMs are designed to transfer data in fixed-size bursts. Initiating a transfer takes some cycles, but after that the burst of data is transferred very quickly (one data item per cycle). Subsequent accesses may also be faster if they are in the vincinity of each other. Getting good performance out of an SDRAM-based memory subsystem requires that the programmer pays attention to the size and location of data items. Ensuring that data objects are as small as possible, and related objects are stored either close to each other, or really far from each other (see Chapter 3.3), is imperative to high bandwidth operation. All cycle values referred to in this document are bus cycles, not CPU core cycles. = SDRAM operation = == Overview == The Dreamcast has 16MB of main memory, supplied in the form of two 8MB SDRAM chips. These chips are clocked at the SH4's full bus frequency, 100MHz. Each of the two main memory SDRAM chips in the Dreamcast is 512k x 32 bits x 4 banks large. The two chips are connected in tandem to the CPU's 64bit bus - one chip handles the upper 32 bits of each access, the other the lower 32 bits - so the configuration is (from the CPU's point of view) identical to having a single 512k x 64 bits x 4 banks SDRAM chip. Address/control bus ||| +---------------------------|||--------------------------------------------+ | ||| | | +++--------------------+++---+++--------------------- ... ---+++ | | ||| ||| ||| | | ||| Bank 0 ||| Bank 1 ... | | ||| +-----------+ ||| +-----------+ | | +------+ | Row 0 | +------+ | Row 0 | | | | Bank |---| Row 1 | | Bank |---| Row 1 | ... Bank k-1 | | | ctrl | | ... | | ctrl | | ... | | | +------+ | Row n-1 | +------+ | Row n-1 | | | +-----------+ +-----------+ | | ||||||||| ||||||||| | | +-----------+ +-----------+ | | |Sense Amps | |Sense amps | | | +-----------+ +-----------+ ......... | | ||||||||| +--------+ ||||||||| ||||||||| | | +++++++++----|Bus ctrl|------+++++++++---- ... -+++++++++ | | +--------+ | +-------------------------------||||---------------------------------------+ |||| Data bus Figure 2.1.1: Model of an SDRAM chip: n rows x m bits/row x k banks An SDRAM chip has one set of address/control pins, and one set of data pins. These make up the SDRAM's interface to the outside world. (See fig. 2.1.1) Inside the chip, there are several (usually two or four) identical submodules called 'banks'. Each bank contains three parts: Bank control circuitry, a memory array, and a row of sense amplifiers. The memory array, in turn, is made up of a set of rows of bits. A row can be subdivided into a set of words, each of which is the size of the data bus. The length of a row is usually equal to (or a bit smaller than) the number of rows in the memory array. Each bank covers one segment of the addressable space; that is, the highest 1 or 2 bits of the address is used to select bank. Row address is given using the following address bits, and finally the column index is given using the lowest-order address bits. Before a given memory cell can be accessed, the appropriate row must be activated in the right bank. Activation connects it to the sense amplifiers, which will translate the small (0.5v or less) charges in the memory array to acceptable CMOS levels. Once the row is active, its contents can be read/written over the data bus. One row can be active in each bank, independent of the other banks. Activation takes a few cycles. If another row already is active in that bank, then that row must first be deactivated. That procedure also takes a few cycles. When reading/writing to the SDRAM, the bus control module will transfer data between the appropriate portions of the active row in the bank in question and the data bus. The bus control module allows the rows to be many times longer than the width of the data bus. In addition to this, the memory cells leak power; inactive rows leak slowly, active rows leak quickly. Therefore, the rows periodically need to be rewritten (typically once every 4ms). A row must not be open too long either (typically max 100us). The normal refresh handles both these issues. == Commands == A few different commands can be sent to the SDRAM on the control/address bus, here is a subset: {| class=wikitable ! Command ! Description |- | REF | Deactivates all active rows, and refreshes one row in each bank (the SDRAM keeps an internal counter which specifies which row is next to be refreshed). |- | ACTIV(bank, row) | Activates the given row in the given bank. No other row must be currently active in that bank. |- | PRE(bank) | 'Precharges', that is, deactivates the currently active row in the given bank. If no row is active in the bank, this is a no-op. |- | PALL | Precharges all banks. |- | READ(bank, column) | Reads a burst of data from the currently active row in the given bank, starting at the specified column. The data will be written to the databus. |- | WRIT(bank, column) | Writes a burst of data to the currently active row in the given bank, starting at the specified column. The data will be read from the databus. |- | READA(bank, column) | Reads a burst of data, then precharges the bank. |- | WRITA(bank, column) | Writes a burst of data, then precharges the bank. |} == Read/write operation == READ/READA commands initiate a series ('burst') of consecutive reads from the active row. There is no need for more communication after the command has been sent; all reads will be carried out without any handshaking. Each read ('beat') will deliver one full set of data to the data bus (8/16/32/64 bits, depending on the data bus width of the SDRAM), and then update the reading address within the row in anticipation of the next beat. The number of beats in a burst has to be set by the CPU when the SDRAM is initialized. Normal values are 1, 2, 4, 8 beats, or enough beats to deliver the whole row. The reading address must be aligned to an integer word boundary. As the read progresses, the next address is computed in one out of a few different ways. The most commonly used scheme is the sequential burst sequence: The access address is increased to the next word address modulo (burst length) -- that is, if the current burst length is 4, and (access address) modulo 4 == 3, then the next access address will be 3 words back, rather than 1 word ahead. This mode allows CPUs to begin fetching a cacheline at an arbitrary position within the line - if the word at offset #2 into a 4-word cacheline is immediately needed by the CPU, it can fetch the words in order 2, 3, 0, 1 by starting a fetch at word 2. Write operation is identical to read operation, except that the SDRAM will read from the address pins, rather than write to them. Also, as there is no write operation that writes only a subset of a word, there is one disable/enable signal available per byte; the bus controller can assert only some of those signals, thereby telling the SDRAM to only update some of the bytes of the next word to be written. == Aborting and pipelining bus transactions == A burst read/write sequence can be prematurely aborted by issuing another read/write command to the SDRAM which will result in new bus access before the first burst sequence has finished. When issuing a read/write, the bank number and column address given on the address bus will be latched into the SDRAM. Once the first data word is read/written via the data bus, the contents on the address and control buses is no longer needed. Another command can then be given while one of the banks is still reading/writing via the data bus, as long as that command will not directly interfere with the ongoing bus transaction. Suitable commands can be row activation/deactivation in another bank, or a read/write command for one of the banks. (The read/write command must not be sent too soon however, or the ongoing bus transaction will be aborted before completion.) By overlapping data bus transfers and command issuing, the SDRAM can reach throughput rates closer to its theoretical maximum: 1 data word per cycle. = SDRAM in the Dreamcast = As the Dreamcast has two 32bit SDRAMs in parallel, and the bus to the SDRAMs is 64bit wide, this chapter will assume the simplified view that there is a single 64bit SDRAM chip in the system. The fictionary '64bit SDRAM' has 2kB/row, 512 rows, and 4 banks. This means that each bank spans 4MB of memory. An address can be split into bank-, row- and column-bits in the following manner: bbrr rrrr rrrr rccc cccc c000 <-- 24bit memory address | | | | bank row column sub-8byte position The SH4 has a bus state controller, which operates in parallel with the rest of the SH4 core. The SH4 bus runs at 100MHz, which is half the SH4 core frequency. == Access philosophy == The SH4 will always access the SDRAM in 32-byte chunks (4-beat bursts) - even when doing non-cached reads/writes. [When doing non-cached writes, the SH4 will tell the SDRAM what data to ignore using some bus control signals.] Because all DMA uses the SH4's on-board DMA controller to generate the addresses, DMA also accesses the SDRAM in 32-byte chunks. Thus there are only two operations which are of interest to the programmer: the 32-byte read, and the 32-byte write. The bus state controller keeps track of which banks have open rows, and omits unnecessary PRE/ACTIV commands whenever possible. The bus state controller can be in two modes. In the first mode ('RASDown', which is setup by the BootROM code), read/write commands are issued as READs/WRITs, and thus leaves the accessed row active after the operation. The bus state controller keeps track of which rows are open in which banks, and omits unnecessary PRE/ACTIV commands whenever possible (when there is a 'row hit'). The only way that rows become deactivated is via 'row misses' and the periodically issued REF commands. This mode gives better performance, unless the row hit rate is exceptionally low. In the second mode, read/write commands are issued as READAs/WRITAs, and thus deactivate the row after the operation. This means that one ACTIV command must be issued before each READA/WRITA. This mode has lower maximum throughput, but may be faster when executing algorithms that have bad row hit/miss ratio. The bus state controller will not pipeline CPU accesses, only DMA accesses. This means that when the CPU requests a memory access, the bus state controller will wait until the data bus is idle before issuing any commands to the SDRAM. Normally, the bus state controller will run in RASDown mode. The BootROM code sets up the bus state controller to operate in this mode. == Access timing in RASDown mode == ACTIV(bank, row) takes 3 cycles. PRE(bank) takes 2 cycles. READ(column) takes 3 cycles for setup, and then 4 cycles during which the data arrives (one beat per bus cycle). WRIT(column) begins writing data immediately: 4 cycles to receive the data. However, the WRITE command must come at least 2 cycles into the operation (some control bus signals may be delayed that much since the previous bus access). The setup time of one CPU access can not be overlapped with the data access time of a previous CPU access. However, DMA accesses will pipeline in this fashion, and since they are massively sequential, there will be a lot of row hits which results in a transfer speed close to 8 bytes/cycle. The values in Table 3.2.1 indicate that the maximum read speed for CPU would be 450MB/s, maximum write speed at 600MB/s, and maximum DMA speed (both read and write) at 800MB/s. When CPU or DMA requests a memory access to a given address, the SH4 will issue different commands to the SDRAM: * If the correct row is active in the bank in question ('row hit'), the READ/WRIT is sent directly to the SDRAM. * If no row is active in the bank in question ('no row active'), an ACTIV command is sent, followed by the READ/WRIT. This case occurs very rarely in the Dreamcast. * If another row is active in the bank in question ('row miss'), a PRE command is first issued to close that row. This is followed by an ACTIV to activate the appropriate row, and finally the READ/WRIT is given. See table 3.2.1 for cycle timings of the different cases. Figure 3.2.5 deserves a comment: According to the SDRAM specification, one of the control signals is delayed by two cycles, so the bus state controller must assert the signal two cycles before the bus transaction begins. Since the CPU is unable to predict what that signal should be set to in advance of the bus transaction, the bus state controller has to idle for two cycles while the control signal in question is propagating through the SDRAM. (DMA accesses, on the other hand, are long sequences of increasing addresses. The control signal can then be predicted ahead of time, and the gap between bus transactions eliminated.) Table 3.2.1: Common access timings {| class=wikitable ! Operation ! Cycles ! Figure |- | CPU burst read, no row active | 10 cycles | Fig. 3.2.1 |- | CPU burst read, row hit | 7 cycles | Fig. 3.2.2 |- | CPU burst read, row miss | 12 cycles | Fig. 3.2.3 |- | CPU burst write, no row activ | 7 cycles | Fig. 3.2.4 |- | CPU burst write, row hit | 6 cycles | Fig. 3.2.5 |- | CPU burst write, row miss | 9 cycles | Fig. 3.2.6 |- | DMA burst reads, row hit | 4 cycles each | Fig. 3.2.7 |- | DMA burst writes, row hit | 4 cycles each | Fig. 3.2.8 |} Note: If a row miss happens during the first cycle after a write, the bus state controller will idle for a cycle before sending the PRE command. Chart coding: **** marks the time when a row/column address, or PRE command is being sent ---- and .... mark when burst beats 1,2,3,4 transfer the data ++++ marks when address/data of other memory accesses are being performed (only used in the DMA figures) Cycle 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Row address ************ | | | | | | | | | | | | | | | | | | | | | | | Column address | | | **************************** | | | | | | | | | | | | | | | | Data arrives | | | | | | ----....----.... | | | | | | | | | | | | | | | | Figure 3.2.1: CPU burst read, no row active 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Column address **************************** | | | | | | | | | | | | | | | | | | | Data arrives | | | ----....----.... | | | | | | | | | | | | | | | | | | | Figure 3.2.2: CPU burst read, row hit Cycle 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Precharge ******** | | | | | | | | | | | | | | | | | | | | | | | | Row address | | ************ | | | | | | | | | | | | | | | | | | | | | Column address | | | | | **************************** | | | | | | | | | | | | | | Data arrives | | | | | | | | ----....----.... | | | | | | | | | | | | | | Figure 3.2.3: CPU burst read, row miss 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Row address ************ | | | | | | | | | | | | | | | | | | | | | | | Column address | | | **************** | | | | | | | | | | | | | | | | | | | Data departs | | | --- ... --- ... | | | | | | | | | | | | | | | | | | | Figure 3.2.4: CPU burst write, no row active 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Idle cycles ******** | | | | | | | | | | | | | | | | | | | | | | | | Column address | | **************** | | | | | | | | | | | | | | | | | | | | Data departs | | --- ... --- ... | | | | | | | | | | | | | | | | | | | | Figure 3.2.5: CPU burst write, row hit 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Precharge ******** | | | | | | | | | | | | | | | | | | | | | | | | Row address | | ************ | | | | | | | | | | | | | | | | | | | | | Column address | | | | | **************** | | | | | | | | | | | | | | | | | Data departs | | | | | --- ... --- ... | | | | | | | | | | | | | | | | | Figure 3.2.6: CPU burst write, row miss -1 0 1 2 3 4 5 6 7 8 9 10 11 | | | | | | | | | | | | | Column address 1 | **************** | | | | | | | | | | | | | | | | | | | | | Column address 2 | | | | | ++++++++++++++++ | | | | | | | | | | | | | | | | | Column address 3 | | | | | | | | | ++++++++++++++++ | | | | | | | | | | | | | Read data 0 ++++++++++++++++ | | | | | | | | | | | | | | | | | | | | | | Read data 1 | | | | ----....----.... | | | | | | | | | | | | | | | | | | Read data 2 | | | | | | | | ++++++++++++++++ | | | | | | | | | | | | | | Figure 3.2.7: DMA burst reads, row hit -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 | | | | | | | | | | | | | Column address 0 ++++ | | | | | | | | | | | | | | | | | | | | | | | | | Column address 1 | | | | **** | | | | | | | | | | | | | | | | | | | | | Column address 2 | | | | | | | | ++++ | | | | | | | | | | | | | | | | | Data departs 0 ++++++++++++++++ | | | | | | | | | | | | | | | | | | | | | | Data departs 1 | | | | ----....----.... | | | | | | | | | | | | | | | | | | Data departs 2 | | | | | | | | ++++++++++++++++ | | | | | | | | | | | | | | Figure 3.2.8: DMA burst writes, row hit == Optimizing memory access patterns == * Align your data structures such that they span as few cache lines as possible (16-byte align vectors, 32-byte align matrices). * If you have a group of related data items, which are going to be accessed at roughly the same time, and there will not be many accesses elsewhere in that bank, then put them into the same row by 2kB-aligning the group of items; this avoids some row activations/deactivations. * If performing some kind of streaming operation (wading through lots of data and performing some simple operation on it), put each data stream into a separate memory bank; this avoids lots of unnecessary row activations/deactivations. * Remember that the cache is direct-mapped. If you are interleaving accesses to two arrays that both are aligned to at least 16kB, there is a risk of cache thrashing. Offset one array some bytes to the side to solve that problem. * Use PREF to fetch data some cycles before you'll be accessing it. If you don't prefetch appropriately, a cachemiss later on will stall the entire SH4 pipeline until the data is available (8+ CPU-cycles from SDRAM). * If you are creating a data stream from scratch -- not modifying existing data at those locations -- then use MOVCA to allocate cache lines without causing memory reads. This way avoids reading in dummy data (due to cache misses & line fills) which is soon going to be overwritten anyway. If you're not going to access the data shortly either, use the Store Queues to write out the data. * When you are writing out a data stream, and you will not overwrite it in the near future, use the OCBWB instruction to force the data to be written back to memory. The two main reasons for triggering cache write-backs manually are that you can avoid memory contention to some degree, and spurious cache writebacks later on may cause lots of SDRAM active row switching. Again, Store Queues is an alternative. * Keep in mind that Store Queues bypass the cache: If previously have read from a memory area, and subsequently write to it using Store Queues, use the OCBI instruction to invalidate the corresponding cache lines. Otherwise the cache might contain stale data. == Accessing other memory areas == When switching between writing to the SDRAM, and writing to other memory areas (either to other memory, or to memory-mapped devices), idle cycles may be inserted. A 32-byte burst to the Tile Accelerator seems to usually take roughly 9 cycles, give or take max 2. The Tile Accelerator might be busy (this happens mainly when starting/ending a new list type, or when submitting degenerate/invalid primitives); then the access will stall for a while (delays up to 500 cycles have been observed). = References = * The bus state controller and SDRAM interface of the SH4 are well described in the SH7750 Hardware Manual. * A detailed description on how to setup an SH4-SDRAM system is found in Application Note #92, named "SH-4 Interface to SDRAM". * The KM432S2030CT-G8 SDRAM (which is used for main memory in some Euro DCs, at least) documentation is available from Samsung. c6b5fc65f91079fe8da14f86f2a458ebc5db3d52 1475 1474 2022-12-08T20:13:49Z Unknown user 0 Darc moved page [[Editing Efficient usage of the Dreamcast RAM]] to [[Efficient usage of the Dreamcast RAM]]: error in page title wikitext text/x-wiki Written by bogglez = Introduction = SDRAMs are essentially DRAMs on steroids, with a minor interface on top of them that allows some degree of pipelining. SDRAMs are designed to transfer data in fixed-size bursts. Initiating a transfer takes some cycles, but after that the burst of data is transferred very quickly (one data item per cycle). Subsequent accesses may also be faster if they are in the vincinity of each other. Getting good performance out of an SDRAM-based memory subsystem requires that the programmer pays attention to the size and location of data items. Ensuring that data objects are as small as possible, and related objects are stored either close to each other, or really far from each other (see Chapter 3.3), is imperative to high bandwidth operation. All cycle values referred to in this document are bus cycles, not CPU core cycles. = SDRAM operation = == Overview == The Dreamcast has 16MB of main memory, supplied in the form of two 8MB SDRAM chips. These chips are clocked at the SH4's full bus frequency, 100MHz. Each of the two main memory SDRAM chips in the Dreamcast is 512k x 32 bits x 4 banks large. The two chips are connected in tandem to the CPU's 64bit bus - one chip handles the upper 32 bits of each access, the other the lower 32 bits - so the configuration is (from the CPU's point of view) identical to having a single 512k x 64 bits x 4 banks SDRAM chip. Address/control bus ||| +---------------------------|||--------------------------------------------+ | ||| | | +++--------------------+++---+++--------------------- ... ---+++ | | ||| ||| ||| | | ||| Bank 0 ||| Bank 1 ... | | ||| +-----------+ ||| +-----------+ | | +------+ | Row 0 | +------+ | Row 0 | | | | Bank |---| Row 1 | | Bank |---| Row 1 | ... Bank k-1 | | | ctrl | | ... | | ctrl | | ... | | | +------+ | Row n-1 | +------+ | Row n-1 | | | +-----------+ +-----------+ | | ||||||||| ||||||||| | | +-----------+ +-----------+ | | |Sense Amps | |Sense amps | | | +-----------+ +-----------+ ......... | | ||||||||| +--------+ ||||||||| ||||||||| | | +++++++++----|Bus ctrl|------+++++++++---- ... -+++++++++ | | +--------+ | +-------------------------------||||---------------------------------------+ |||| Data bus Figure 2.1.1: Model of an SDRAM chip: n rows x m bits/row x k banks An SDRAM chip has one set of address/control pins, and one set of data pins. These make up the SDRAM's interface to the outside world. (See fig. 2.1.1) Inside the chip, there are several (usually two or four) identical submodules called 'banks'. Each bank contains three parts: Bank control circuitry, a memory array, and a row of sense amplifiers. The memory array, in turn, is made up of a set of rows of bits. A row can be subdivided into a set of words, each of which is the size of the data bus. The length of a row is usually equal to (or a bit smaller than) the number of rows in the memory array. Each bank covers one segment of the addressable space; that is, the highest 1 or 2 bits of the address is used to select bank. Row address is given using the following address bits, and finally the column index is given using the lowest-order address bits. Before a given memory cell can be accessed, the appropriate row must be activated in the right bank. Activation connects it to the sense amplifiers, which will translate the small (0.5v or less) charges in the memory array to acceptable CMOS levels. Once the row is active, its contents can be read/written over the data bus. One row can be active in each bank, independent of the other banks. Activation takes a few cycles. If another row already is active in that bank, then that row must first be deactivated. That procedure also takes a few cycles. When reading/writing to the SDRAM, the bus control module will transfer data between the appropriate portions of the active row in the bank in question and the data bus. The bus control module allows the rows to be many times longer than the width of the data bus. In addition to this, the memory cells leak power; inactive rows leak slowly, active rows leak quickly. Therefore, the rows periodically need to be rewritten (typically once every 4ms). A row must not be open too long either (typically max 100us). The normal refresh handles both these issues. == Commands == A few different commands can be sent to the SDRAM on the control/address bus, here is a subset: {| class=wikitable ! Command ! Description |- | REF | Deactivates all active rows, and refreshes one row in each bank (the SDRAM keeps an internal counter which specifies which row is next to be refreshed). |- | ACTIV(bank, row) | Activates the given row in the given bank. No other row must be currently active in that bank. |- | PRE(bank) | 'Precharges', that is, deactivates the currently active row in the given bank. If no row is active in the bank, this is a no-op. |- | PALL | Precharges all banks. |- | READ(bank, column) | Reads a burst of data from the currently active row in the given bank, starting at the specified column. The data will be written to the databus. |- | WRIT(bank, column) | Writes a burst of data to the currently active row in the given bank, starting at the specified column. The data will be read from the databus. |- | READA(bank, column) | Reads a burst of data, then precharges the bank. |- | WRITA(bank, column) | Writes a burst of data, then precharges the bank. |} == Read/write operation == READ/READA commands initiate a series ('burst') of consecutive reads from the active row. There is no need for more communication after the command has been sent; all reads will be carried out without any handshaking. Each read ('beat') will deliver one full set of data to the data bus (8/16/32/64 bits, depending on the data bus width of the SDRAM), and then update the reading address within the row in anticipation of the next beat. The number of beats in a burst has to be set by the CPU when the SDRAM is initialized. Normal values are 1, 2, 4, 8 beats, or enough beats to deliver the whole row. The reading address must be aligned to an integer word boundary. As the read progresses, the next address is computed in one out of a few different ways. The most commonly used scheme is the sequential burst sequence: The access address is increased to the next word address modulo (burst length) -- that is, if the current burst length is 4, and (access address) modulo 4 == 3, then the next access address will be 3 words back, rather than 1 word ahead. This mode allows CPUs to begin fetching a cacheline at an arbitrary position within the line - if the word at offset #2 into a 4-word cacheline is immediately needed by the CPU, it can fetch the words in order 2, 3, 0, 1 by starting a fetch at word 2. Write operation is identical to read operation, except that the SDRAM will read from the address pins, rather than write to them. Also, as there is no write operation that writes only a subset of a word, there is one disable/enable signal available per byte; the bus controller can assert only some of those signals, thereby telling the SDRAM to only update some of the bytes of the next word to be written. == Aborting and pipelining bus transactions == A burst read/write sequence can be prematurely aborted by issuing another read/write command to the SDRAM which will result in new bus access before the first burst sequence has finished. When issuing a read/write, the bank number and column address given on the address bus will be latched into the SDRAM. Once the first data word is read/written via the data bus, the contents on the address and control buses is no longer needed. Another command can then be given while one of the banks is still reading/writing via the data bus, as long as that command will not directly interfere with the ongoing bus transaction. Suitable commands can be row activation/deactivation in another bank, or a read/write command for one of the banks. (The read/write command must not be sent too soon however, or the ongoing bus transaction will be aborted before completion.) By overlapping data bus transfers and command issuing, the SDRAM can reach throughput rates closer to its theoretical maximum: 1 data word per cycle. = SDRAM in the Dreamcast = As the Dreamcast has two 32bit SDRAMs in parallel, and the bus to the SDRAMs is 64bit wide, this chapter will assume the simplified view that there is a single 64bit SDRAM chip in the system. The fictionary '64bit SDRAM' has 2kB/row, 512 rows, and 4 banks. This means that each bank spans 4MB of memory. An address can be split into bank-, row- and column-bits in the following manner: bbrr rrrr rrrr rccc cccc c000 <-- 24bit memory address | | | | bank row column sub-8byte position The SH4 has a bus state controller, which operates in parallel with the rest of the SH4 core. The SH4 bus runs at 100MHz, which is half the SH4 core frequency. == Access philosophy == The SH4 will always access the SDRAM in 32-byte chunks (4-beat bursts) - even when doing non-cached reads/writes. [When doing non-cached writes, the SH4 will tell the SDRAM what data to ignore using some bus control signals.] Because all DMA uses the SH4's on-board DMA controller to generate the addresses, DMA also accesses the SDRAM in 32-byte chunks. Thus there are only two operations which are of interest to the programmer: the 32-byte read, and the 32-byte write. The bus state controller keeps track of which banks have open rows, and omits unnecessary PRE/ACTIV commands whenever possible. The bus state controller can be in two modes. In the first mode ('RASDown', which is setup by the BootROM code), read/write commands are issued as READs/WRITs, and thus leaves the accessed row active after the operation. The bus state controller keeps track of which rows are open in which banks, and omits unnecessary PRE/ACTIV commands whenever possible (when there is a 'row hit'). The only way that rows become deactivated is via 'row misses' and the periodically issued REF commands. This mode gives better performance, unless the row hit rate is exceptionally low. In the second mode, read/write commands are issued as READAs/WRITAs, and thus deactivate the row after the operation. This means that one ACTIV command must be issued before each READA/WRITA. This mode has lower maximum throughput, but may be faster when executing algorithms that have bad row hit/miss ratio. The bus state controller will not pipeline CPU accesses, only DMA accesses. This means that when the CPU requests a memory access, the bus state controller will wait until the data bus is idle before issuing any commands to the SDRAM. Normally, the bus state controller will run in RASDown mode. The BootROM code sets up the bus state controller to operate in this mode. == Access timing in RASDown mode == ACTIV(bank, row) takes 3 cycles. PRE(bank) takes 2 cycles. READ(column) takes 3 cycles for setup, and then 4 cycles during which the data arrives (one beat per bus cycle). WRIT(column) begins writing data immediately: 4 cycles to receive the data. However, the WRITE command must come at least 2 cycles into the operation (some control bus signals may be delayed that much since the previous bus access). The setup time of one CPU access can not be overlapped with the data access time of a previous CPU access. However, DMA accesses will pipeline in this fashion, and since they are massively sequential, there will be a lot of row hits which results in a transfer speed close to 8 bytes/cycle. The values in Table 3.2.1 indicate that the maximum read speed for CPU would be 450MB/s, maximum write speed at 600MB/s, and maximum DMA speed (both read and write) at 800MB/s. When CPU or DMA requests a memory access to a given address, the SH4 will issue different commands to the SDRAM: * If the correct row is active in the bank in question ('row hit'), the READ/WRIT is sent directly to the SDRAM. * If no row is active in the bank in question ('no row active'), an ACTIV command is sent, followed by the READ/WRIT. This case occurs very rarely in the Dreamcast. * If another row is active in the bank in question ('row miss'), a PRE command is first issued to close that row. This is followed by an ACTIV to activate the appropriate row, and finally the READ/WRIT is given. See table 3.2.1 for cycle timings of the different cases. Figure 3.2.5 deserves a comment: According to the SDRAM specification, one of the control signals is delayed by two cycles, so the bus state controller must assert the signal two cycles before the bus transaction begins. Since the CPU is unable to predict what that signal should be set to in advance of the bus transaction, the bus state controller has to idle for two cycles while the control signal in question is propagating through the SDRAM. (DMA accesses, on the other hand, are long sequences of increasing addresses. The control signal can then be predicted ahead of time, and the gap between bus transactions eliminated.) Table 3.2.1: Common access timings {| class=wikitable ! Operation ! Cycles ! Figure |- | CPU burst read, no row active | 10 cycles | Fig. 3.2.1 |- | CPU burst read, row hit | 7 cycles | Fig. 3.2.2 |- | CPU burst read, row miss | 12 cycles | Fig. 3.2.3 |- | CPU burst write, no row activ | 7 cycles | Fig. 3.2.4 |- | CPU burst write, row hit | 6 cycles | Fig. 3.2.5 |- | CPU burst write, row miss | 9 cycles | Fig. 3.2.6 |- | DMA burst reads, row hit | 4 cycles each | Fig. 3.2.7 |- | DMA burst writes, row hit | 4 cycles each | Fig. 3.2.8 |} Note: If a row miss happens during the first cycle after a write, the bus state controller will idle for a cycle before sending the PRE command. Chart coding: **** marks the time when a row/column address, or PRE command is being sent ---- and .... mark when burst beats 1,2,3,4 transfer the data ++++ marks when address/data of other memory accesses are being performed (only used in the DMA figures) Cycle 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Row address ************ | | | | | | | | | | | | | | | | | | | | | | | Column address | | | **************************** | | | | | | | | | | | | | | | | Data arrives | | | | | | ----....----.... | | | | | | | | | | | | | | | | Figure 3.2.1: CPU burst read, no row active 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Column address **************************** | | | | | | | | | | | | | | | | | | | Data arrives | | | ----....----.... | | | | | | | | | | | | | | | | | | | Figure 3.2.2: CPU burst read, row hit Cycle 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Precharge ******** | | | | | | | | | | | | | | | | | | | | | | | | Row address | | ************ | | | | | | | | | | | | | | | | | | | | | Column address | | | | | **************************** | | | | | | | | | | | | | | Data arrives | | | | | | | | ----....----.... | | | | | | | | | | | | | | Figure 3.2.3: CPU burst read, row miss 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Row address ************ | | | | | | | | | | | | | | | | | | | | | | | Column address | | | **************** | | | | | | | | | | | | | | | | | | | Data departs | | | --- ... --- ... | | | | | | | | | | | | | | | | | | | Figure 3.2.4: CPU burst write, no row active 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Idle cycles ******** | | | | | | | | | | | | | | | | | | | | | | | | Column address | | **************** | | | | | | | | | | | | | | | | | | | | Data departs | | --- ... --- ... | | | | | | | | | | | | | | | | | | | | Figure 3.2.5: CPU burst write, row hit 0 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | | Precharge ******** | | | | | | | | | | | | | | | | | | | | | | | | Row address | | ************ | | | | | | | | | | | | | | | | | | | | | Column address | | | | | **************** | | | | | | | | | | | | | | | | | Data departs | | | | | --- ... --- ... | | | | | | | | | | | | | | | | | Figure 3.2.6: CPU burst write, row miss -1 0 1 2 3 4 5 6 7 8 9 10 11 | | | | | | | | | | | | | Column address 1 | **************** | | | | | | | | | | | | | | | | | | | | | Column address 2 | | | | | ++++++++++++++++ | | | | | | | | | | | | | | | | | Column address 3 | | | | | | | | | ++++++++++++++++ | | | | | | | | | | | | | Read data 0 ++++++++++++++++ | | | | | | | | | | | | | | | | | | | | | | Read data 1 | | | | ----....----.... | | | | | | | | | | | | | | | | | | Read data 2 | | | | | | | | ++++++++++++++++ | | | | | | | | | | | | | | Figure 3.2.7: DMA burst reads, row hit -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 | | | | | | | | | | | | | Column address 0 ++++ | | | | | | | | | | | | | | | | | | | | | | | | | Column address 1 | | | | **** | | | | | | | | | | | | | | | | | | | | | Column address 2 | | | | | | | | ++++ | | | | | | | | | | | | | | | | | Data departs 0 ++++++++++++++++ | | | | | | | | | | | | | | | | | | | | | | Data departs 1 | | | | ----....----.... | | | | | | | | | | | | | | | | | | Data departs 2 | | | | | | | | ++++++++++++++++ | | | | | | | | | | | | | | Figure 3.2.8: DMA burst writes, row hit == Optimizing memory access patterns == * Align your data structures such that they span as few cache lines as possible (16-byte align vectors, 32-byte align matrices). * If you have a group of related data items, which are going to be accessed at roughly the same time, and there will not be many accesses elsewhere in that bank, then put them into the same row by 2kB-aligning the group of items; this avoids some row activations/deactivations. * If performing some kind of streaming operation (wading through lots of data and performing some simple operation on it), put each data stream into a separate memory bank; this avoids lots of unnecessary row activations/deactivations. * Remember that the cache is direct-mapped. If you are interleaving accesses to two arrays that both are aligned to at least 16kB, there is a risk of cache thrashing. Offset one array some bytes to the side to solve that problem. * Use PREF to fetch data some cycles before you'll be accessing it. If you don't prefetch appropriately, a cachemiss later on will stall the entire SH4 pipeline until the data is available (8+ CPU-cycles from SDRAM). * If you are creating a data stream from scratch -- not modifying existing data at those locations -- then use MOVCA to allocate cache lines without causing memory reads. This way avoids reading in dummy data (due to cache misses & line fills) which is soon going to be overwritten anyway. If you're not going to access the data shortly either, use the Store Queues to write out the data. * When you are writing out a data stream, and you will not overwrite it in the near future, use the OCBWB instruction to force the data to be written back to memory. The two main reasons for triggering cache write-backs manually are that you can avoid memory contention to some degree, and spurious cache writebacks later on may cause lots of SDRAM active row switching. Again, Store Queues is an alternative. * Keep in mind that Store Queues bypass the cache: If previously have read from a memory area, and subsequently write to it using Store Queues, use the OCBI instruction to invalidate the corresponding cache lines. Otherwise the cache might contain stale data. == Accessing other memory areas == When switching between writing to the SDRAM, and writing to other memory areas (either to other memory, or to memory-mapped devices), idle cycles may be inserted. A 32-byte burst to the Tile Accelerator seems to usually take roughly 9 cycles, give or take max 2. The Tile Accelerator might be busy (this happens mainly when starting/ending a new list type, or when submitting degenerate/invalid primitives); then the access will stall for a while (delays up to 500 cycles have been observed). = References = * The bus state controller and SDRAM interface of the SH4 are well described in the SH7750 Hardware Manual. * A detailed description on how to setup an SH4-SDRAM system is found in Application Note #92, named "SH-4 Interface to SDRAM". * The KM432S2030CT-G8 SDRAM (which is used for main memory in some Euro DCs, at least) documentation is available from Samsung. c6b5fc65f91079fe8da14f86f2a458ebc5db3d52 Editing Efficient usage of the Dreamcast RAM 0 696 1476 2022-12-08T20:13:49Z Unknown user 0 Darc moved page [[Editing Efficient usage of the Dreamcast RAM]] to [[Efficient usage of the Dreamcast RAM]]: error in page title wikitext text/x-wiki #REDIRECT [[Efficient usage of the Dreamcast RAM]] a96a5d5bf4a7c0d673025d27fa207d6b0c6d18ac Development 0 2 1477 1031 2022-12-08T20:13:59Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] ba5fea122b807ce1b19ce4086797e620f5f3fc05 Getting Started with Dreamcast development 0 694 1487 1486 2022-12-09T05:45:40Z Unknown user 0 /* Dependencies */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Considering and choosing a Dreamcast debug link solution (serial, BBA, LAN) ** Include charts comparing the pros and cons of each solution * Configuring and compiling the toolchain, KOS, and KOS ports * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== ====Debian/Ubuntu-based Linux==== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ====Fedora-based Linux==== On Fedora, install the required dependencies using the following command: sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ Many of these dependencies should be installed already on a typical Fedora-based system, but we've chosen to list them all here for good measure. ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 7950572d2d6f77c6d1d9591b4bf4e0ca8f51b799 1488 1487 2022-12-09T05:46:41Z Unknown user 0 /* WIP NOTES */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== ====Debian/Ubuntu-based Linux==== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ====Fedora-based Linux==== On Fedora, install the required dependencies using the following command: sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ Many of these dependencies should be installed already on a typical Fedora-based system, but we've chosen to list them all here for good measure. ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking. Be careful if adjusting makeopts for more than one job, as this can lead to build failure. It is recommended to keep this setting at -j1. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 482e07d93ccc6856c0777fd29f28b5148b654962 1489 1488 2022-12-09T06:16:06Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== ====Debian/Ubuntu-based Linux==== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ====Fedora-based Linux==== On Fedora, install the required dependencies using the following command: sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ Many of these dependencies should be installed already on a typical Fedora-based system, but we've chosen to list them all here for good measure. ====Arch-based Linux==== On Arch, install the required dependencies using the following command: sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng Many of these dependencies should be installed already on a typical Arch-based system, but we've chosen to list them all here for good measure. ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, and whenever you are working on your Dreamcast project: source /opt/toolchains/dc/kos/environ.sh Build KOS: make KOS is now built. Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 7650008c2622d31b79f1ea336d4ec4b93c356b9b 1490 1489 2022-12-09T06:19:34Z Unknown user 0 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== ====Debian/Ubuntu-based Linux==== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ====Fedora-based Linux==== On Fedora, install the required dependencies using the following command: sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ Many of these dependencies should be installed already on a typical Fedora-based system, but we've chosen to list them all here for good measure. ====Arch-based Linux==== On Arch, install the required dependencies using the following command: sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng Many of these dependencies should be installed already on a typical Arch-based system, but we've chosen to list them all here for good measure. ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 282360b6251a93b3a8b863b5a50f51137dd33ef4 1491 1490 2022-12-09T06:21:08Z Unknown user 0 /* Introduction */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== ====Debian/Ubuntu-based Linux==== First, we'll need to install dependencies before building the toolchain. On Debian/Ubuntu-based systems, install the required dependencies using the following command: sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev Many of these dependencies should be installed already on a typical Debian/Ubuntu-based system, but we've chosen to list them all here for good measure. ====Fedora-based Linux==== On Fedora, install the required dependencies using the following command: sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ Many of these dependencies should be installed already on a typical Fedora-based system, but we've chosen to list them all here for good measure. ====Arch-based Linux==== On Arch, install the required dependencies using the following command: sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng Many of these dependencies should be installed already on a typical Arch-based system, but we've chosen to list them all here for good measure. ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 2652f0cedb0cc16094a03bdd3320bf8389e8166b 1492 1491 2022-12-09T06:29:52Z Unknown user 0 /* Dependencies */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= Explain the differences (costs, performance, and other considerations) among the options. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. b889418a50bb754c3fdb9b45b82ddd20fc8ed333 1493 1492 2022-12-09T06:40:56Z Unknown user 0 /* Choosing a debug link solution */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 65b5b392c408c213121ac0623271bc29b4fe3ddc 1494 1493 2022-12-09T07:02:42Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 851977a42748082bb7c371a62492c9afd5af49f5 1495 1494 2022-12-09T07:06:20Z Unknown user 0 /* Dependencies */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 414ac28ffac8c484780de250bf21f95bd8d8ea40 1496 1495 2022-12-09T07:18:45Z Unknown user 0 /* Choosing a debug link solution */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. Run the following now, '''and''' ''whenever'' you are working on your Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 4c39a168bc46fbc32f90d0174cff50d261f75522 1497 1496 2022-12-09T07:29:18Z Unknown user 0 /* Setting up the environment settings */ wikitext text/x-wiki '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' <div style="float:right;">__TOC__</div> =WIP NOTES= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. c768aaaaede0373a3c3a23d8159558f11539fef9 1498 1497 2022-12-10T04:27:06Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 59a6a29793bc061411bb7810eab666c4e7c209ae 1499 1498 2022-12-16T18:48:01Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 49b71783602dec56af074bf39c51ce3c3eed1532 1500 1499 2022-12-16T18:53:47Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Toolchain Patches=== If you are on macOS, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. d594fcde34f05bb4753a266a4d539e5a223505e5 1501 1500 2022-12-16T18:57:48Z Unknown user 0 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Toolchain Patches=== If you are on macOS, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 69e2b80d90f12099fca807618bab99dbef654eda 1502 1501 2022-12-16T20:39:01Z Unknown user 0 /* macOS */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Toolchain Patches=== If you are on macOS, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 1816d329ebdd29711a276c74be310c129a7a7b89 1503 1502 2022-12-17T18:21:08Z Unknown user 0 /* macOS Toolchain Patches */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 3148ac07b278135fb4421c5896178dc6d65a6917 1504 1503 2022-12-17T18:21:44Z Unknown user 0 /* macOS Patches */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS AS Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib ===macOS Intel Patches=== In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include -I/usr/local/opt/libpng/include LDFLAGS += -L/usr/local/opt/jpeg/lib -L/usr/local/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include -I/usr/local/opt/libpng/include LDFLAGS += -L/usr/local/opt/jpeg/lib -L/usr/local/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/libpng/include LDFLAGS += -L/usr/local/opt/libpng/lib In utils/vqenc/Makefile, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 47cfb326a2f4d68d57bb6650daf7e8149e937f8b 1505 1504 2022-12-17T18:37:09Z Unknown user 0 /* macOS AS Patches */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS AS Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib In utils/vqenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib ===macOS Intel Patches=== In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include -I/usr/local/opt/libpng/include LDFLAGS += -L/usr/local/opt/jpeg/lib -L/usr/local/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include -I/usr/local/opt/libpng/include LDFLAGS += -L/usr/local/opt/jpeg/lib -L/usr/local/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/libpng/include LDFLAGS += -L/usr/local/opt/libpng/lib In utils/vqenc/Makefile, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 13896f77f3bf77bf7e120ef89d7a42730bde9673 1506 1505 2022-12-17T18:47:23Z Unknown user 0 /* macOS Intel Patches */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS AS Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib In utils/vqenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib ===macOS Intel Patches=== In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib In utils/vqenc/Makefile, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 2ed8bbe94e71be242f06861eaab986aab7da2023 1507 1506 2022-12-17T18:47:39Z Unknown user 0 /* macOS AS Patches */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Apple Silicon Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib In utils/vqenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib ===macOS Intel Patches=== In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib In utils/vqenc/Makefile, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 336e093a794b251e20857e403a8c0c03d42b02cc 1508 1507 2022-12-17T19:05:39Z Unknown user 0 /* macOS Ventura on an Intel or Apple Silicon processor */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Apple Silicon Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib In utils/vqenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib ===macOS Intel Patches=== In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib In utils/vqenc/Makefile, add: CFLAGS += -I/usr/local/opt/jpeg/include LDFLAGS += -L/usr/local/opt/jpeg/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 467ede0d49027800fdac3be2aa9296e3054f78a8 1509 1508 2022-12-17T19:05:59Z Unknown user 0 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Apple Silicon Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib In utils/vqenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. fdd56bb90bad2103a1fbd54b4e4f1996d0fe75e2 1510 1509 2022-12-17T19:21:46Z Unknown user 0 /* macOS Ventura on an Intel or Apple Silicon processor */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng '''Important Note''': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added the path to your scripts, then run the following commands in your Terminal session before compiling KOS: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===macOS Apple Silicon Patches=== The Makefiles for the following utils need to be modified to properly build on macOS using Homebrew's installed libs. In utils/dcbumpgen/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/kmgenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib In utils/makeip/src/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/libpng/lib In utils/vqenc/Makefile, after the existing CFLAGS and LDFLAGS lines, add: CFLAGS += -I/opt/homebrew/opt/jpeg/include -I/opt/homebrew/opt/libpng/include LDFLAGS += -L/opt/homebrew/opt/jpeg/lib -L/opt/homebrew/opt/libpng/lib ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. ae4e92e09bdc1c752f67b7797b167b79d4f1f118 1511 1510 2022-12-17T19:22:03Z Unknown user 0 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng '''Important Note''': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added the path to your scripts, then run the following commands in your Terminal session before compiling KOS: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 5140078a7c87dfdb4f62cd55fd0b1b161e781582 1512 1511 2022-12-17T19:27:43Z Unknown user 0 /* macOS Ventura on an Intel or Apple Silicon processor */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng '''Important Note''': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added the path to your scripts, then run the following commands in your Terminal session: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib You may want to add these two lines to your '''~/.zprofile''' file so they are automatically run at the beginning of every Terminal session. ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. f09e9ae6c565e83e7c334bd61f9db2bf57677c61 1513 1512 2022-12-17T19:30:56Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng '''Important Note''': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to both the GCC 9 (SH4) and GCC 8 (AICA) directories. In gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 89f72a0afa2db0d388b762f6d66fa751dbe92446 1514 1513 2022-12-17T19:44:35Z Unknown user 0 /* macOS Apple Silicon Toolchain Patches */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng '''Important Note''': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to '''both''' the SH4 and AICA GCC directories (e.g. gcc-9.3.0/ and gcc-8.4.0/ for the ''testing'' profile). In gcc-X.X.X/gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc-X.X.X/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. c26a2d22d6fdb3e26e067c7e35d64bbe03947435 1515 1514 2022-12-17T21:51:39Z Unknown user 0 /* macOS Ventura on an Intel or Apple Silicon processor */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to '''both''' the SH4 and AICA GCC directories (e.g. gcc-9.3.0/ and gcc-8.4.0/ for the ''testing'' profile). In gcc-X.X.X/gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc-X.X.X/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 03eaf7c4ede05eb80d67f98c665ff850ccaa1856 1516 1515 2022-12-17T21:53:45Z Unknown user 0 /* macOS Ventura on an Intel or Apple Silicon processor */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===macOS Apple Silicon Toolchain Patches=== If you are on macOS on Apple Silicon, there are several patches that must be applied in order for the toolchain to build correctly. These patches most be applied to '''both''' the SH4 and AICA GCC directories (e.g. gcc-9.3.0/ and gcc-8.4.0/ for the ''testing'' profile). In gcc-X.X.X/gcc/config.host, find the following two lines and comment them out by adding a # character to the beginning. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" will become #out_host_hook_obj=host-darwin.o #host_xmake_file="${host_xmake_file} x-darwin" and in gcc-X.X.X/gcc/config/host-darwin.c, below the existing #include declarations, add: #include "hosthooks.h" #include "hosthooks-def.h" const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 9579689eb0133d28352c9edc5d517254ae133e73 1517 1516 2022-12-18T01:02:03Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 346aa1fb9631ab7e3548c3a2abaa3ce34f313b3e 1519 1517 2022-12-18T02:37:29Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 2f3370d8b81ee4918d0c203956a98a5b52d9cfeb 1536 1519 2022-12-22T18:27:05Z Unknown user 0 /* Compiling and running an example program */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 5613edb01c9b39f8f7420a24d7b4f11c105aadac File:Dcload-2022-12-17.zip 6 697 1518 2022-12-18T02:34:08Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=ZIP file containing bootable CDI images of the latest versions of dcload-ip 2.0.0 with DHCP fixes and dcload-serial 1.0.6 as of 2022-12-17 Dummied and will fit on 80min/700MB CD-Rs}} |date=2022-12-17 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 03ede71bf95497c57db981d51605f727a1e6a3a3 Dcload-ip 0 23 1520 758 2022-12-18T02:38:29Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. The program is mostly intended for homebrew development, but can also be used with special programs designed to make use of it like [https://github.com/zeldin/dc-virtcd Marcus Comstedt's dc-virtcd]. [[:File:Dcload-2022-12-17.zip|Download the latest versions of dcload-ip 2.0.0 and dcload-serial 1.0.6 as of December 17, 2022]] '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip main repository] - maintained by SiZiOUS * [https://github.com/Moopthehedgehog/dcload-ip dcload-ip experimental development (also has prebuilt images and binaries)] - maintained by Moopthehedgehog {{DISPLAYTITLE:dcload-ip}} d16e4a0e02347af31bd96253bedbec399ddddadb 1522 1520 2022-12-18T02:41:27Z Unknown user 0 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. The program is mostly intended for homebrew development, but can also be used with special programs designed to make use of it like [https://github.com/zeldin/dc-virtcd Marcus Comstedt's dc-virtcd]. [[:File:Dcload-2022-12-17.zip|Download the latest versions of dcload-ip 2.0.0 and dcload-serial 1.0.6 as of December 17, 2022]] '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip main repository] - maintained by SiZiOUS {{DISPLAYTITLE:dcload-ip}} c9be62c714a9f26eef2834da4a257016e538a1aa Dcload-serial 0 698 1521 2022-12-18T02:38:57Z Unknown user 0 Created page with "[[:File:Dcload-2022-12-17.zip|Download the latest versions of dcload-ip 2.0.0 and dcload-serial 1.0.6 as of December 17, 2022]]" wikitext text/x-wiki [[:File:Dcload-2022-12-17.zip|Download the latest versions of dcload-ip 2.0.0 and dcload-serial 1.0.6 as of December 17, 2022]] 7acca2e9dc1b52cd50c057cd84ae84e60633e570 1523 1521 2022-12-18T02:41:44Z Unknown user 0 wikitext text/x-wiki dcload-serial is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a serial cable as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the BIOS. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the serial port. It also provides chainloaded programs with a standard syscall interface for communicating with a connected PC. The program is mostly intended for homebrew development, but can also be used with special programs. [[:File:Dcload-2022-12-17.zip|Download the latest versions of dcload-ip 2.0.0 and dcload-serial 1.0.6 as of December 17, 2022]] [https://github.com/sizious/dcload-serial dcload-serial main repository] - maintained by SiZiOUS {{DISPLAYTITLE:dcload-serial}} 33a339b0913ca2359d0ee7215247bb2c629b5f4c 32MB RAM expansion 0 284 1524 1011 2022-12-19T00:50:36Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. The Dreamcast port of [[NetBSD]] can also be built to take advantage of the additional RAM. At the moment, the only known software able to take advantage of the 32MB RAM expansion is the [https://github.com/tsowell/scummvm-dreamcast/blob/dcalt-backend/backends/platform/dcalt/README.md Alternate ScummVM backend for Dreamcast] by tsowell. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. {| class="wikitable" style="float:right; margin-left: 10px;" |+32MB-patched BIOS image testing |- |1.004 vanilla |UNTESTED, PROBABLY WORKS |- |1.01c vanilla |UNTESTED, PROBABLY WORKS |- |1.01d vanilla |WORKS |- |1.01d w/ region free patch ("link83") |WORKS |- |1.01d w/ region free patch alt intro ("link83") |WORKS |- |1.01d Treamcast |UNTESTED |- |1.022 ("no mil-CD BIOS") |NOT INCLUDED ON DISC, UNTESTED |- |jc 1.300 regular intro |WORKS |- |jc 1.300 alt intro |UNTESTED, SHOULD WORK |- |jc 1.310 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |jc 1.320 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |dreamboot 1.0.0 |WORKS |- |dreamboot 1.0.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.1 |WORKS |- |dreamboot 1.0.1 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.2 |WORKS |- |dreamboot 1.0.2 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.1.0 |WORKS |- |dreamboot 1.1.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader regular intro |WORKS |- |dreamshell boot loader regular intro No GDROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader alt intro |WORKS |- |dreamshell boot loader alt intro No GD-ROM |WORKS |- |dreamshell sd_loader_with.bios |WORKS |} A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* While most of the BIOS images on the disc have been tested, not all have. See the testing chart to the right. "WORKS" means that the Dreamcast boots up while using this BIOS and boots DreamShell and/or Crazy Taxi. There is a high likelihood that some games will exhibit bugs. So far, bugs have been noticed in Sonic Adventure and Phantasy Star Online v2. More testing to come. ** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! *** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] * A memory testing utility is available as well. [[:File:Memtest.tar.gz]] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. 3e60eec04a9e772695bd981e16a7072183c49820 1525 1524 2022-12-21T21:55:59Z Unknown user 0 wikitext text/x-wiki By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of RAM in the Dreamcast. Existing games and applications will very likely not be able to address the RAM, but applications built with a patched version of [[KallistiOS]] are able to address all 32MB. The Dreamcast port of [[NetBSD]] can also be built to take advantage of the additional RAM. At the moment, the only known software able to take advantage of the 32MB RAM expansion is the [https://github.com/tsowell/scummvm-dreamcast/blob/dcalt-backend/backends/platform/dcalt/README.md Alternate ScummVM backend for Dreamcast] by tsowell. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. {| class="wikitable" style="float:right; margin-left: 10px;" |+32MB-patched BIOS image testing |- |1.004 vanilla |UNTESTED, PROBABLY WORKS |- |1.01c vanilla |UNTESTED, PROBABLY WORKS |- |1.01d vanilla |WORKS |- |1.01d w/ region free patch ("link83") |WORKS |- |1.01d w/ region free patch alt intro ("link83") |WORKS |- |1.01d Treamcast |UNTESTED |- |1.022 ("no mil-CD BIOS") |NOT INCLUDED ON DISC, UNTESTED |- |jc 1.300 regular intro |WORKS |- |jc 1.300 alt intro |UNTESTED, SHOULD WORK |- |jc 1.310 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |jc 1.320 regular intro |WORKS |- |jc 1.310 alt intro |WORKS |- |dreamboot 1.0.0 |WORKS |- |dreamboot 1.0.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.1 |WORKS |- |dreamboot 1.0.1 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.0.2 |WORKS |- |dreamboot 1.0.2 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamboot 1.1.0 |WORKS |- |dreamboot 1.1.0 No GD-ROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader regular intro |WORKS |- |dreamshell boot loader regular intro No GDROM |UNTESTED, SHOULD WORK |- |dreamshell boot loader alt intro |WORKS |- |dreamshell boot loader alt intro No GD-ROM |WORKS |- |dreamshell sd_loader_with.bios |WORKS |} A DreamShell image with 32MB patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing the MX29L3211 32 megabit chips to accommodate triple-BIOS mods! * *'''WARNING'''* While most of the BIOS images on the disc have been tested, not all have. See the testing chart to the right. "WORKS" means that the Dreamcast boots up while using this BIOS and boots DreamShell and/or Crazy Taxi. There is a high likelihood that some games will exhibit bugs. So far, bugs have been noticed in Sonic Adventure and Phantasy Star Online v2. More testing to come. ** Seriously! We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! *** Download [https://mega.nz/file/rltniDbC#_TEfFduymRzpl3hdEJjvWuH7RHVIOoNZlKFUujOsfxo DreamShell 32MB BIOS Flasher Image] * A memory testing utility is available as well. [[:File:Memtest.tar.gz]] See [https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] for more information on the modification for now. ==NetBSD Support== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. b46bcaba23de95cc01fe068d942f8a751b370e84 1526 1525 2022-12-21T23:41:36Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM. Without a BIOS mod, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. * [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] * [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey] [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download DreamShell 32MB BIOS Flasher Image (link needs updating) ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b amx3-32mb https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. 91e109b5b61872267c3f3d4b0f9a24cac7d42b87 1527 1526 2022-12-21T23:44:08Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM. Without a BIOS mod, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. * [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] * [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey] [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download DreamShell 32MB BIOS Flasher Image (link needs updating) ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b amx3-32mb https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X d2978d1e3245dda8217b23db4ae98f6538d2a6d7 1528 1527 2022-12-22T00:13:20Z Unknown user 0 /* BIOS Flasher */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM. Without a BIOS mod, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. * [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] * [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey] [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b amx3-32mb https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X c87c8182463c9ac850c94f9a04e432ad3a9d46cc 1529 1528 2022-12-22T00:16:22Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM. Without a BIOS mod, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b amx3-32mb https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 47a0150a3fe496ba101542921383fff110fac409 1531 1529 2022-12-22T00:51:05Z Unknown user 0 /* KallistiOS */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM. Without a BIOS mod, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b amx3-32mb https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d kilobytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The hardware_memsize() function can be called to retrieve the running system's size */ printf("hardware_memsize() reports this system has %d kilobytes.\n", hardware_memsize()); printf("This is a %s console!\n", (hardware_memsize() == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_RAM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_RAM ? "Yes!" : "No...")); /* mm_top() can be used to get the top address of memory */ printf("Top of memory is 0x%0x!\n", mm_top()); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 5e97a81071fd57121cb854ccde3470f3c20f3e41 1532 1531 2022-12-22T01:15:36Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b amx3-32mb https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d kilobytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The hardware_memsize() function can be called to retrieve the running system's size */ printf("hardware_memsize() reports this system has %d kilobytes.\n", hardware_memsize()); printf("This is a %s console!\n", (hardware_memsize() == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_RAM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_RAM ? "Yes!" : "No...")); /* mm_top() can be used to get the top address of memory */ printf("Top of memory is 0x%0x!\n", mm_top()); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 216d10e7fe7cdf130854560075e9b71ffafc53f9 Cepawiel 0 699 1530 2022-12-22T00:26:49Z Unknown user 0 Created page with "Colton Pawielski is a Dreamcast developer. * [https://github.com/cepawiel cepawiel on GitHub] * [https://gitlab.com/cepawiel cepawiel on GitLab]" wikitext text/x-wiki Colton Pawielski is a Dreamcast developer. * [https://github.com/cepawiel cepawiel on GitHub] * [https://gitlab.com/cepawiel cepawiel on GitLab] c735366469bdf48cb501aa8d7005e406e65b95d1 DCDigital 0 14 1533 799 2022-12-22T02:04:19Z Unknown user 0 wikitext text/x-wiki '''DCDigital''' (formerly known as '''DCHDMI''') is a modification kit created by chriz2600 and citrus3000psi which adds native digital audio and video (via HDMI output) to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. Both the hardware design and the firmware are open source, allowing anyone to legally clone the mod kit. * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. All current hardware modifications, such as overclocking, 32MB RAM expansion, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCDigital. [https://shop.dansprojects.com/dchdmi-pre-order.html Dan's Projects link to purchase] === Links === * [http://www.dansprojects.com/dchdmi_install.html Installation instructions] * DCDigital Installation video: [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * [https://dc.i74.de/ Latest firmware] * [https://github.com/citrus3000psi/DCHDMI-Hardware Hardware design files] on github * [https://github.com/chriz2600/DreamcastHDMI/ Firmware source code] on github {{DCWiki:Stub}} dcd1ca28c00f5323743bb54405c367adbe077067 1534 1533 2022-12-22T03:17:20Z Unknown user 0 wikitext text/x-wiki '''DCDigital''' (formerly known as '''DCHDMI''') is a modification kit originally created by [https://www.black-dog.tech/ Black-Dog Tech] (v1) and now [https://www.pixelfx.co/ PixelFX] (v2). The modification adds native digital audio and video output (via HDMI port) to the Sega Dreamcast. The modification taps into digital video signals on the Dreamcast motherboard to generate pristine HDMI compliant video output. Installation requires advanced surface-mount soldering skills. The original version distributed by Black-Dog Tech is now discontinued, but both the hardware design and the firmware of the original version are open source, which has led to widespread availability through clone manufacturers. The second version developed by PixelFX expands the feature set and brings it in line with their PS1Digital and N64Digital products, but it is a proprietary product. Black-Dog Tech version: * Games that support the Dreamcast VGA video mode can output direct native 480p, line-doubled 960p, or 1080p created by placing a black border around line-doubled 960p. * Games that do not support the Dreamcast VGA video mode can output direct native 240p/480i, deinterlaced 480i, line-doubled deinterlaced 960p, or 1080p created by placing a black border around line-doubled deinterlaced 960p. Only bob deinterlacing available. * 960p is not a standard resolution and may not be compatible with all TVs or monitors. * H2QX smoothing filter available, but relaxed non-HDMI compliant timings when turned on PixelFX version: * Custom zoom and aspect ratio * Configurable horizontal and vertical interpolation * 1440p (1920x1440) resolution video output * Custom video modelines * Slotmask/shadowmask filters * Advanced scanline options * Added weave and motion-adaptive interlacing * XBR or H2QX smoothing * CEC remote control * pseudo-HDR * Support for Naomi arcade systems * Fully HDMI compliant All current hardware modifications, such as overclocking, 32MB RAM expansion, BIOS modifications, optical drive replacements, 12V line removal, etc. are known to be compatible with DCDigital. === Links === * PixelFX Version: [https://docs.pixelfx.co/DCDigital-Comparison.html Product comparison], [https://www.pixelfx.co/product-page/dcdigital-kit Purchase page], [https://docs.pixelfx.co/DCDigital-Details.html Documentation], [https://docs.pixelfx.co/DCDigital-Installation.html Installation instructions] * Original Version: [http://www.dansprojects.com/dchdmi_install.html Installation instructions] and installation video in [https://www.youtube.com/watch?v=0c3iSYbLoH8 English], [https://www.bilibili.com/video/av54547024 Chinese] * Original Version: [https://dc.i74.de/ Latest firmware], [https://github.com/citrus3000psi/DCHDMI-Hardware Hardware design files], [https://github.com/chriz2600/DreamcastHDMI/ Firmware source code] on github {{DCWiki:Stub}} 4d09a647253c854bf252feb5facaad8f6216f2eb BIOS modification 0 12 1535 727 2022-12-22T04:08:06Z Unknown user 0 wikitext text/x-wiki The Dreamcast's BIOS chip can be replaced (or a secondary chip added) to remove region checks, A/V connectivity compatibility checks, and add new features. Examples of custom BIOS versions include japanese-cake's BIOS hacks [https://japanese-cake.livejournal.com/8489.html v1.031] and [https://japanese-cake.livejournal.com/10056.html v1.032] and cpasjuste's [https://github.com/Cpasjuste/dreamboot DreamBoot]. * v0 consoles (5V): Use MX29F1610. * v1 and v2 consoles (3.3V): Use MX29LV160TMC or MX29L3211 (32 megabit, double BIOS). {{DCWiki:Stub}} 868a66ab707b72ae32889a57e38debd95cab1210 Getting Started with Dreamcast development 0 694 1537 1536 2022-12-22T19:00:41Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE], ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 6e61d461a204f5ad1db91d6a1224e5cb7e134675 1538 1537 2022-12-22T19:01:12Z Unknown user 0 /* Burning your project to CD and distributing */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =This article is incomplete -- actively being worked on!= '''BEWARE: THIS ARTICLE IS CURRENTLY A WIP''' This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link and self-booting CD-R. * Steps required for Windows 10/WSL, macOS/Intel, macOS/Apple Silicon, Debian/Ubuntu Linux, and Fedora Linux ** Steps should be pretty similar for the *nix OSs besides package managers and dependencies * Setting up KOS and compiling an example program * Executing the sample program using a debug link ** Include up-to-date ready made CDIs for dcload-serial and dcload-ip * Burning a project to CD and preparing for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. fd920bd42328697db9d857c491bb04d4d938b31c VMU hardware overview 0 147 1539 470 2022-12-27T22:14:43Z Unknown user 0 fleshed out clock, RAM, ROM, power source, timers, input wikitext text/x-wiki [[File:VMU Device.jpg|thumb|Visual Memory Unit]] * '''CPU''': 8-bit Sanyo LC86K87 * '''Clock''': 32.8KHz quartz oscillator or 879.2kHz RC oscillator when operating standalone or 6MHz CF oscillator when plugged into the controller * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes of additional WRAM * '''ROM''': 4KB OS/firmware functionality, 16KB system BIOS program area * '''Flash''': 128 KB (200 blocks) with 8-bit FAT filesystem * '''Power source''': Two CR2032 batteries with auto-off function and low-battery detection circuit * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Input''': 4-button D-pad, 2 general-purpose buttons (A, B), MODE, SLEEP * '''Timer''': Base Timer (14-bit binary up counter), 2xTimer Circuits (16-bit timer/counter with pulse generator) * '''Serial Interface''': Dedicated Maple interface (VMU-to-Dreamcast) or Synchronous 8-bit serial interface with 2 transfer channels (VMU-to-VMU) abad81cf27f53c6d4ec715fc28ba2f8fb24887c5 1549 1539 2022-12-27T22:35:52Z Unknown user 0 Added a link to the manual wikitext text/x-wiki [[File:VMU Device.jpg|thumb|Visual Memory Unit]] * '''CPU''': 8-bit Sanyo LC86K87 * '''Clock''': 32.8KHz quartz oscillator or 879.2kHz RC oscillator when operating standalone or 6MHz CF oscillator when plugged into the controller * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes of additional WRAM * '''ROM''': 4KB OS/firmware functionality, 16KB system BIOS program area * '''Flash''': 128 KB (200 blocks) with 8-bit FAT filesystem * '''Power source''': Two CR2032 batteries with auto-off function and low-battery detection circuit * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Input''': 4-button D-pad, 2 general-purpose buttons (A, B), MODE, SLEEP * '''Timer''': Base Timer (14-bit binary up counter), 2xTimer Circuits (16-bit timer/counter with pulse generator) * '''Serial Interface''': Dedicated Maple interface (VMU-to-Dreamcast) or Synchronous 8-bit serial interface with 2 transfer channels (VMU-to-VMU) [[:File:Vmu_Manual.pdf|Instruction Manual]] adc77e03b01daad9bd33ef7cecb3711227c9eae5 File:Vmu Manual.pdf 6 136 1540 412 2022-12-27T22:19:22Z Unknown user 0 /* Summary */ wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." da58649fb66e9e198d7b97a3a7a5e96ea05b73b3 1541 1540 2022-12-27T22:20:01Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. === Limitations ==== Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. === Errors === There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." 529d18420d1e4cb8c1a172e175f49bb23e5bcc49 1542 1541 2022-12-27T22:20:17Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. === Errors === There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." 6d75c0b576d789b77400f19bb38191da73b18302 1543 1542 2022-12-27T22:24:13Z Unknown user 0 Undo revision 1542 by [[Special:Contributions/GyroVorbis|GyroVorbis]] ([[User talk:GyroVorbis|talk]]) wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. === Limitations ==== Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. === Errors === There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." 529d18420d1e4cb8c1a172e175f49bb23e5bcc49 1544 1543 2022-12-27T22:24:25Z Unknown user 0 Undo revision 1541 by [[Special:Contributions/GyroVorbis|GyroVorbis]] ([[User talk:GyroVorbis|talk]]) wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." da58649fb66e9e198d7b97a3a7a5e96ea05b73b3 1545 1544 2022-12-27T22:24:47Z Unknown user 0 Undo revision 1540 by [[Special:Contributions/GyroVorbis|GyroVorbis]] ([[User talk:GyroVorbis|talk]]) wikitext text/x-wiki == Summary == Official VMU manual 7de3f2f37f40bd0f27160fd213176f5f6f8d5022 File:VMU.pdf 6 100 1546 292 2022-12-27T22:25:30Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. === Errors === There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." c44633fe7aa01bacb6026c2f24ca71530b15b133 1547 1546 2022-12-27T22:26:20Z Unknown user 0 /* Limitations */ wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer, but are crucial for emulation. === Errors === There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." 152a1a3f759732e915a4f4a93d7b89efd80b1d4c 1548 1547 2022-12-27T22:26:33Z Unknown user 0 /* Limitations */ wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer but are crucial for emulation. === Errors === There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." 2fcf9c59ff2250073397fd9d124bf6dfa73eb13f Development 0 2 1550 1477 2022-12-27T22:37:47Z Unknown user 0 Added link to standalone VMU development wikitext text/x-wiki === Getting started === ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[Yam 20to4 SH4 maths]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 4aa9b4938b6eb89601b55c760161e07574cabacf 1586 1550 2022-12-28T05:43:44Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] f726959da4beb468cfa712899431a9b9349275ab VMU development 0 99 1551 471 2022-12-27T22:58:20Z Unknown user 0 Added overview and skeleton contents wikitext text/x-wiki === Overview === Developing standalone games for the VMU is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active an ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point for what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== ==== C Code ==== === Architecture === === Testing === ==== Emulators ==== ==== Physical Device ==== === References === Here are some reference resources to get started * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 642c332cb49cb5a9571ec4c9cf9639f0c3e7ab63 1552 1551 2022-12-27T22:59:45Z Unknown user 0 wikitext text/x-wiki === Overview === Developing standalone games for the VMU is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== ==== C Code ==== === Architecture === === Testing === ==== Emulators ==== ==== Physical Device ==== === References === Here are some reference resources to get started * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 7525885b90f1e20c9104eae639acc039eb6fffde 1553 1552 2022-12-28T03:21:24Z Unknown user 0 wikitext text/x-wiki === Overview === Developing standalone games for the VMU is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Architecture === === Testing === ==== Emulators ==== The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device. === References === Here are some reference resources to get started * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} a82113d0071d55f7b3c00c2dac84109882b3e0da 1554 1553 2022-12-28T03:26:20Z Unknown user 0 wikitext text/x-wiki === Overview === Developing standalone games for the VMU is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf VMU Development Manual]] is typically what is referenced while programming for the VMU. === Architecture === === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser === References === Here are some reference resources to get started * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 6c52b1492e1af2c81e3a2bbb7fdd70bfca11c6f3 1555 1554 2022-12-28T03:27:52Z Unknown user 0 wikitext text/x-wiki === Overview === Developing standalone games for the VMU is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. === Architecture === === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser === References === Here are some reference resources to get started * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking link Dmitry.gr VMU hacking] * [http://slum.online/dreamcast/ Slum Online development] * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * VMU documentation in PDF: [[:File:VMU.pdf]] {{DCWiki:Stub}} 5b72fa91089898e6eab38b683466533566cb995e 1563 1555 2022-12-28T03:57:44Z Unknown user 0 wikitext text/x-wiki === Overview === Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual {{DCWiki:Stub}} 905c790407aa90a78f35156c850e6586af933ac9 1566 1563 2022-12-28T04:06:49Z Unknown user 0 wikitext text/x-wiki === Overview === Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual {{DCWiki:Stub}} f09b71b64c0ffce1fbead56c6fe07fa2313fd792 1573 1566 2022-12-28T04:36:59Z Unknown user 0 wikitext text/x-wiki === Overview === [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual {{DCWiki:Stub}} b1a6dd9aad76471ca53c1a55a68874f75b71eafe 1574 1573 2022-12-28T04:38:05Z Unknown user 0 wikitext text/x-wiki === Overview === [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual {{DCWiki:Stub}} 219b5dfea878347cb535ce86381059468afca4f1 1575 1574 2022-12-28T04:39:32Z Unknown user 0 wikitext text/x-wiki === Overview === [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual fcced124c0a79a0306e09541b758afef029aebe2 1577 1575 2022-12-28T05:03:25Z Unknown user 0 wikitext text/x-wiki === Overview === [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ac39a564aeb5b682a88b4378bc6c1256bc623620 1578 1577 2022-12-28T05:09:01Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 251877a0fe093f000c671e33d56022385ae8d152 1580 1578 2022-12-28T05:12:34Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex A23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual d30e6f706fdc593c9c42da2fa461afdb9ea645f4 1581 1580 2022-12-28T05:15:26Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex A23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 894a585f6d376870a4b9ee9e831b6bc2844db326 1582 1581 2022-12-28T05:16:45Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear). These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual bed35a9219c6cf6d80f954918d685d2d7918fcf8 1583 1582 2022-12-28T05:21:18Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device or to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the LDF and STF undocumented VMU opcodes (supported by Waterbear) respectively. These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 02d1141fd55e9d4433d9466858b5f7480cf4c3c1 File:Maple Bus Electronics Block Diagram.png 6 700 1556 2022-12-28T03:29:18Z Unknown user 0 wikitext text/x-wiki Depicts how host and devices are physically connected to the bus a5a7999b149da66ad8d7a0695918704e8f03688d File:Maple Bus Hardware Communication.png 6 701 1557 2022-12-28T03:30:25Z Unknown user 0 wikitext text/x-wiki Depicts how the bus is shared for communication between host and devices b8ca60e87c62d611bde5ba0ca459003838a03e9b File:Maple Bus Start Sequence.png 6 702 1558 2022-12-28T03:44:13Z Unknown user 0 wikitext text/x-wiki Shows signaling for start sequence c74eac72a835b110be9b624b1f9492dce4a3dd7e File:Maple Bus End Sequence.png 6 703 1559 2022-12-28T03:46:53Z Unknown user 0 wikitext text/x-wiki Shows the signals which complete a packet transmission 9435d8d99ac76128933f23622173a015f614b348 File:Maple Bus Clocking Phases.png 6 704 1560 2022-12-28T03:53:10Z Unknown user 0 wikitext text/x-wiki Shows the 3 clocking phases for each bit 5c79f6b0b05042636d81fcee381cb00eac001674 File:Maple Bus Data.png 6 705 1561 2022-12-28T03:55:44Z Unknown user 0 wikitext text/x-wiki Shows how each bit is transmitted bb6be185be8c8de7908143041b818cc4e730600b Maple bus 0 113 1562 317 2022-12-28T03:57:25Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, rumble pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|center|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|center|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence [[File:Maple Bus Start Sequence.png|center|Maple Bus Start Sequence]] === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|center|Maple Bus End Sequence]] === Data Bits === For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled [[File:Maple Bus Clocking Phases.png|center|Maple Bus Clocking Phases]] There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|center|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 03069b8fab7c9b3cc0ce6e9da0910204ac84cc55 1564 1562 2022-12-28T03:58:28Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, rumble pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|left|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|left|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence [[File:Maple Bus Start Sequence.png|left|Maple Bus Start Sequence]] === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|left|Maple Bus End Sequence]] === Data Bits === For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled [[File:Maple Bus Clocking Phases.png|left|Maple Bus Clocking Phases]] There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|left|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 823345e4c2c82053e5e92aeb77a1967841e69f58 1565 1564 2022-12-28T03:58:49Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, rumble pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|center|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|center|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence [[File:Maple Bus Start Sequence.png|center|Maple Bus Start Sequence]] === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|center|Maple Bus End Sequence]] === Data Bits === For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled [[File:Maple Bus Clocking Phases.png|center|Maple Bus Clocking Phases]] There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|center|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 03069b8fab7c9b3cc0ce6e9da0910204ac84cc55 1567 1565 2022-12-28T04:06:54Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|center|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|center|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence [[File:Maple Bus Start Sequence.png|center|Maple Bus Start Sequence]] === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|center|Maple Bus End Sequence]] === Data Bits === For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled [[File:Maple Bus Clocking Phases.png|center|Maple Bus Clocking Phases]] There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|center|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 8c4d93fcde627297eb28e1d2dd96ede66eac1039 1568 1567 2022-12-28T04:20:46Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence [[File:Maple Bus Start Sequence.png|Maple Bus Start Sequence]] === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|Maple Bus End Sequence]] === Data Bits === For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled [[File:Maple Bus Clocking Phases.png|Maple Bus Clocking Phases]] There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 33665479975ae21c486a7751f7ec76883441a87d File:VMU Memory Map.png 6 706 1569 2022-12-28T04:24:52Z Unknown user 0 wikitext text/x-wiki A high-level look at the VMU's segmented address space 97f1494b70fd3a774c8d2112925b73a2bae3959f File:VMU Tetris Screenshot.gif 6 707 1570 2022-12-28T04:30:57Z Unknown user 0 wikitext text/x-wiki Screenshot of Marcus Comstedt's "VMU Tetris" 01faa11fef9dd549cd4410466094d1db4452c23d File:ElysianVMU Flash Editor.jpg 6 708 1571 2022-12-28T04:32:48Z Unknown user 0 wikitext text/x-wiki ElysianVMU's flash editor 3e38de314647c2ae67058ad40709fd0d8d2a186b File:Multicolored VMUs.jpg 6 709 1572 2022-12-28T04:36:05Z Unknown user 0 wikitext text/x-wiki Various different faces of the VMU f52126790b2ff86076cfdf7e354be00509c7fd6f File:VMU Animator.zip 6 710 1576 2022-12-28T04:59:55Z Unknown user 0 wikitext text/x-wiki Original VMU Animator Tool for Windows from Booyaka d30ba5c2e722c47f6ce6a743c26293347a422c70 File:VMU System Block Diagram.png 6 711 1579 2022-12-28T05:10:42Z Unknown user 0 wikitext text/x-wiki Block diagram of the VMU and its various peripherals 8b91fdcf81c418d408ce498495deef5f3bc4be36 Fast SH4 Vertex Processing 0 84 1584 968 2022-12-28T05:43:04Z Unknown user 0 GyroVorbis moved page [[Yam 20to4 SH4 maths]] to [[Fast SH4 Vertex Processing]]: The title made no sense previously. lol. wikitext text/x-wiki [http://yam.20to4.net/dreamcast/hints/index.html Original source] ==Vector Math Instructions== The SH4 CPU featrues some nice builtin math operations. I saw some people trying to speed up their code by using approximations with integer codes and other tricks. That may work but on the SH4 good code that makes use of the builtin instructions will outperform in the most situations. There is not much sense in trying to replace that functions at all since they are already pretty fast. ===<code>FIPR</code>=== Computes the dot product of two 4D vectors <code>x1*x2 + y1*y2 + z1*z2 + w1*w2</code> Often used in lighting formulas. ===<code>FTRV</code>=== Muliplies a 4x4 matrix with a 4D vector Usually used to transform vertices, but can also be used to compute "a * b + c" for four floats in parallel. However, the FMAC may perform better in particular situations because the matrix needs to be setup in a special way. ===<code>FSRRA</code>=== Approximates <code>1.0f / sqrt (x)</code> Usually used to normalize a vector. ===<code>FSCA</code>=== Approximates the sine and cosine. Comes in handy when constructing rotation matrices. This one takes the angle as an integer in the range 0...32767 so it's best to redefine angle representations throughout the whole code so that an angle of PI = 16384 or something. This would save the required conversion (range scale and truncation to integer). ===<code>FSQRT</code>=== Computes <code>sqrt (x)</code> This is actually not a special instruction but it's there and comes in handy sometimes although it's slower than FSRRA so rewrite your math formulas (e.g. range falloff lighting) and try to use FSRRA where applicable instead. ===<code>FMAC</code>=== Computes <code>a * b + c</code> This is as fast as normal float addition, subtraction or multiplication, so basically you pay one and get another operation for free. Comes in handy when doing linear interpolation (polygon clipping, table lookups etc). ===<code>FMOV</code> (64 bit)=== This instruction is very important since it can access the second banked set of the FPU registers that are normally used to hold the vector transformation matrix. It's best to avoid switching the fmov mode very often, so rearrange your data layout. It also requires the data to be 64 bit aligned (8 bytes). ==Cache== The cache is very very important. It is so important that it may either save your day or screw up everything. First of all it is important to understand how the cache works. It is a direct mapped cache, i.e. the cache lines are mapped directly onto the addresses of the memory and since it's only 16 KB small the memory at address (n) is mapped onto the same cache line as the location at address (n + 1024*16) which will result in a cache miss. So it's best to avoid such situations which is not always possible especially when working with large amounts of data, e.g. vertex data. That's where the powerful cache control instructions come in... ===<code>PREF</code>=== Prefetches a cache line for the specified address Use this to prefetch the next element in processing loops for large data buffers. The prefetch delay can be hidden by prefetching the next element at the beginning of the loop. ===<code>OCBWB</code>=== Writes back a cache line This one is often used when cache content and memory content need to be synchronized explicitely for DMA transfers since the DMA controllers operate directly on memory. ===<code>OCBI</code>=== Invalidates a cache line This is also used often with DMA functions before reading a memory area that had just been rewritten by a DMA controller. Another way would be to access the memory area as uncached but this might slow down everything. ===<code>OCBP</code>=== Purges a cache line (write back & invalidate) Use this one after your processing loop definitely has finished its operations for one element. The effect is very similar to the store queues except that you cannot read anything from the store queue lines and can write only 32 or 64 bits at once. ===<code>MOVCA.L</code>=== Allocates a cache line for the specified address This one is very important when processing large buffers. While the OCBP instruction can be left out wihtout any performance drops this is does not apply for MOVCA.L. When processing large buffers you often have an input buffer and an output buffer. The input buffer is read, something is done with the elements and they are stored into the output buffer. Without MOVCA.L a store to the output buffer would cause the cache to read a cache line from the output buffer and redirect the store into the cache. This is a total waste, because most of time every byte of the output buffer is only rewritten with new content. That's what the MOVCA.L is for. It tells the cache to reserve a cache line without fetching memory. But be careful this may cause data corruption. There is another cache feature which makes it possible to use half of the operand cache (i.e. 8 KB) as scratchpad RAM. This may be used to hold transformation loop parameters like matrices or something but it also halves the operand cache size which may decrease overall performance of the code. ==Store Queues== These come in handy when flushing vertices to the graphics hardware or to memory. Basically all they are for is batching up 32 bytes of data and flushing it to some location. The store queues can be used to write to main memory but they bypass the cache thus cache synchronization may become an issue. There are some benefits when using the store queues, among them there are two which I think are worth mentioning. First there are two of them each 32 bytes in size and both operate independently, i.e. you can instruct one store queue to flush its contents and write to the other at the same time without stalling the program code. Then there is another nice feature which I call "data cloning". Sometimes you need to clone data for whatever reason. For one normal store and one cloning operation this implies two reads and two writes per element. With appropriate pointer mapping setup you can reduce this to one read and two writes which will boost the performance of your code. The trick is easy to do. All you have to do is telling a store queue to flush with two different addresses. The store queue number is indicated by bit 6 of the flushing address and the other upper bits are the raw address where the store queue content is flushed to. However, each flush instruction will stall the code until the concerned store queue has finished a previous flush operation. So it's best to do something else between two flush instructions. Notice also that the store queues can be used in conjunction with the MMU for mapping the store queue address space to different pieces of hardware which eliminates the need to set up the QARC0 / QARC1 registers. ==Optimizing TnL Loops== This is probably one of the most frequent optimization topics. Always remember the 20-80 rule: 80 percent of the time is spent in 20 percent of the code. Thus first of all identify your bottle necks. For the most cases this will be the graphics routines, or more precicely the transform and lighting part of the graphics routines, since on Dreamcast this stuff is done by the CPU. When doing "complex" transformation and lighting you may get very large loops that do a lot of operations per vertex. Of course it's best to avoid any operations in the first place (culling) but eventually you will have to compute the lighting intensities for 3 light sources, compute the bumpmapping parameters, apply 8 skinning matrices or whatever you are going to do with one vertex. Let's take a simple example which is supposed to apply diffuse and specular lighting to a vertex, transforming the vertex and storing it in a buffer. This may look as follows: <syntaxhighlight lang="c"> do { fetch vertex apply diffuse lighting ((N * L) * material diffuse color * light color) apply specular lighting (pow ((N * H), material shininess) * material specular color * light color) clamp and pack the lighting result to packed 32 bit ARGB apply transformation (matrix) * (x,y,z,1) apply perspective divide (1/w) write back vertex } while (-- count); </syntaxhighlight> Now add a few more things and you will get quite a big loop and you will run out of FPU registers for sure. Additionally this code is subject to bad pipelining since most of the operatations depend on the results of previous operations. So there are a few things we better do in a different way. Normally each vertex does not depend on adjacent vertices in the buffer. The operations applied are the same for each vertex. If we had a lot of CPU cores as the Cell Processor will we could do some parallel processing, but we don't. Still there is a way to speed things up by processing two vertices at a time, but this will work only if there are enough FPU registers left to hold at least some parts of a second vertex. What we do is simply breaking up the loop in independent and simple steps: *apply diffuse lighting *apply specular lighting *clamp and pack lighting result *apply transformation and perspective divide Thus we'll get something like... <syntaxhighlight lang="c"> do { fetch vertex parts apply diffuse lighting store temporary results } while (-- count); do { fetch vertex parts apply specular lighting store temporary results } while (-- count); do { fetch temporary results clamp and pack lighting result store packed values } while (-- count); do { fetch vertex parts apply transformation apply perspective divide store results } while (-- count); </syntaxhighlight> Now we have small and simple loops that can be pipelined much better since there are more spare registers left. Also the loops can be applied in any order and in any combination making the code more flexible. For instance, if you don't need specular lighting then just don't call the specular lighting loop, that's it. The trick now is to run the small loops not over the whole buffer at once but over smaller blocks of the buffer. This way the currently processed vertices will be kept in the cache for each of the many loop iterations. As to my experience a block size of 32 vertices gives the best performance. Decreasing the value may introduce loop startup or function call overhead. Increasing the value may also increase cache misses. It's the same as with network packet sizes: you have to try a little bit to find the best value. a0ee180f3121be09f66bcffa61aa906560342ab0 Yam 20to4 SH4 maths 0 712 1585 2022-12-28T05:43:04Z Unknown user 0 GyroVorbis moved page [[Yam 20to4 SH4 maths]] to [[Fast SH4 Vertex Processing]]: The title made no sense previously. lol. wikitext text/x-wiki #REDIRECT [[Fast SH4 Vertex Processing]] 62dc85107063098c699a7a52f24067febb21a587 BIOS 0 78 1587 452 2022-12-28T05:53:21Z Unknown user 0 wikitext text/x-wiki =Dreamcast= The Sega Dreamcast BIOS has several known revisions: {| class="wikitable" |+Known BIOS images |- ! Version ! Label ! Regions ! HW Revisions ! Notes ! CRC32 ! MD5 ! SHA1 |- |v1.004 |MPR-21068 |Japan |va0 |No support for region flags in flash, hardcoded to Japan |5454841f |37c921eb47532cae8fb70e5d987ce91c |1ea132c0fbbf07ef76789eadc07908045c089bd6 |- |v1.01c |MPR-21871 |PAL | | |2f551bc5 |6679bc5f3006b5bdb019b2781f537373 |1ede8d5be49116a4c6f3fe0961175469537a0434 |- |v1.01d |MPR-21931, MPR-21933 |Japan, U.S., PAL |va1 | |89f2b1a1 |e10c53c2f8b90bab96ead2d368858623 |8951d1bb219ab2ff8583033d2119c899cc81f18c |- |v1.01d (hack) | ??? |Japan |va1 |[[Treamcast]] console BIOS, menu translated to Chinese |cff88d0d |583f96b3e255ed405abc5bdbad8635c0 |e3f84705b183ffded0a349ac7f2ab00be2ab74ee |- |v1.022 |MPR-23588 |Japan, U.S. |va2 |MIL-CD loading support removed |786168f9 |f2cd29d09f3e29984bcea22ab2e006fe |ba8bbb90fdb29525f24f17055dc2c7b2d7674437 |} =VMU= The Visual Memory Unit (or Visual Memory System) has two known revisions: {| class="wikitable" |+Known BIOS images |- ! Version ! Regions ! CRC32 ! MD5 ! SHA1 |- |v1.04 |Japanese |8e0f867a |352578c7f395235439b78034c0c3f483 |b75f616755899dfc6d99f39f36015b20343f0f9f |- |v1.05 |American |c825003a |e7386b97c7da04ba9a0febebe0cba88d |32ba00149d8df942c690fe4913b2f7447b69cf12 |} {{DCWiki:Stub}} c85c7c533b65873b55c901cbd11a359852be3ad6 1588 1587 2022-12-28T05:54:40Z Unknown user 0 wikitext text/x-wiki =Dreamcast= The Sega Dreamcast BIOS has several known revisions: {| class="wikitable" |+Known BIOS images |- ! Version ! Label ! Regions ! HW Revisions ! Notes ! CRC32 ! MD5 ! SHA1 |- |v1.004 |MPR-21068 |Japan |va0 |No support for region flags in flash, hardcoded to Japan |5454841f |37c921eb47532cae8fb70e5d987ce91c |1ea132c0fbbf07ef76789eadc07908045c089bd6 |- |v1.01c |MPR-21871 |PAL | | |2f551bc5 |6679bc5f3006b5bdb019b2781f537373 |1ede8d5be49116a4c6f3fe0961175469537a0434 |- |v1.01d |MPR-21931, MPR-21933 |Japan, U.S., PAL |va1 | |89f2b1a1 |e10c53c2f8b90bab96ead2d368858623 |8951d1bb219ab2ff8583033d2119c899cc81f18c |- |v1.01d (hack) | ??? |Japan |va1 |[[Treamcast]] console BIOS, menu translated to Chinese |cff88d0d |583f96b3e255ed405abc5bdbad8635c0 |e3f84705b183ffded0a349ac7f2ab00be2ab74ee |- |v1.022 |MPR-23588 |Japan, U.S. |va2 |MIL-CD loading support removed |786168f9 |f2cd29d09f3e29984bcea22ab2e006fe |ba8bbb90fdb29525f24f17055dc2c7b2d7674437 |} =VMU= The Visual Memory Unit (or Visual Memory System) BIOS has two known revisions: {| class="wikitable" |+Known BIOS images |- ! Version ! Regions ! CRC32 ! MD5 ! SHA1 |- |v1.04 |Japanese |8e0f867a |352578c7f395235439b78034c0c3f483 |b75f616755899dfc6d99f39f36015b20343f0f9f |- |v1.05 |American |c825003a |e7386b97c7da04ba9a0febebe0cba88d |32ba00149d8df942c690fe4913b2f7447b69cf12 |} {{DCWiki:Stub}} 28ec80c883dba0b3330a33a380534ed9d72829ca VMU mods 0 713 1589 2022-12-28T06:02:17Z Unknown user 0 Created page with "There exist various hardware modifications for the VMU/VMS for things ranging from rechargable batteries and backlit LCD to CPU overclocking and USB power. {{DCWiki:Stub}}" wikitext text/x-wiki There exist various hardware modifications for the VMU/VMS for things ranging from rechargable batteries and backlit LCD to CPU overclocking and USB power. {{DCWiki:Stub}} f9211824192727ba21213591f49a75a6ef5e9a6b 1590 1589 2022-12-28T06:02:25Z Unknown user 0 wikitext text/x-wiki There exist various hardware modifications for the VMU/VMS for things ranging from rechargable batteries and backlit LCD to CPU overclocking and USB power. {{DCWiki:Stub}} c934a81f200f7b5365c218ab7629df4f33545999 1592 1590 2022-12-28T06:04:38Z Unknown user 0 wikitext text/x-wiki There exist various hardware modifications for the VMU/VMS for things ranging from rechargable batteries and backlit LCD screens to CPU overclocking and USB power. {{DCWiki:Stub}} 0f15e762a626dd18c7c78f95701fd3ba53a8e92d 1593 1592 2022-12-28T06:05:09Z Unknown user 0 wikitext text/x-wiki There exist various hardware modifications for the VMU/VMS for things ranging from rechargable batteries and USB power to LCD screens and CPU overclocking. {{DCWiki:Stub}} d7084a761de8dcdf22f8a9b9dc0d714046194098 VMU 0 137 1591 413 2022-12-28T06:03:41Z Unknown user 0 wikitext text/x-wiki * [[VMU_hardware_overview|Hardware Overview]] * [[VMU_development|Development]] * [[VMU_emulators|Emulators]] * [[VMU_mods|Modifications]] {{DCWiki:Stub}} d91361f4cced57006184dd321575ddc5ab57684b 1596 1591 2022-12-28T06:22:31Z Unknown user 0 wikitext text/x-wiki * [[VMU_hardware_overview|Hardware Overview]] * [[VMU_games|Games]] * [[VMU_development|Development]] * [[VMU_emulators|Emulators]] * [[VMU_mods|Modifications]] {{DCWiki:Stub}} 8a50a9b9d226161417e7417581d2da449008ece3 VMU development 0 99 1594 1583 2022-12-28T06:10:08Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to read and write directly to and from flash using the LDF and STF undocumented VMU opcodes (supported by Waterbear) respectively. These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual c92b5b8780ecd4dccb7a58d0201a12a78cc8f17b 1595 1594 2022-12-28T06:12:57Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small delay. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear) respectively. These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual e825a05ba1d8786e757ebe19a65605086a6c9b1e 1599 1595 2022-12-28T06:40:44Z Unknown user 0 /* Grayscale Graphics */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear) respectively. These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 1b349a55c3a5e91ef8b90342bb1d1a7e94e20d9f 1600 1599 2022-12-28T06:41:01Z Unknown user 0 /* Grayscale Graphics */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU opcodes (supported by Waterbear) respectively. These opcodes are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged this to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 415cd0647232f3847fc7e6a1a5a02a4669ff817c 1601 1600 2022-12-28T06:42:19Z Unknown user 0 /* Unconstrained Flash Access */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * DreamShell * VMU Tool * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual e8a68faadea158d018f57d462d38d2df63e0a6fa 1602 1601 2022-12-28T09:53:07Z Unknown user 0 /* Physical Device */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|A brief look at the VMU's segmented address space]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 0e253adae22ac02e9d44c808bfcb923e62a80727 1603 1602 2022-12-28T09:56:30Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 0ea5a6bf0fa367c336b55bc2c410d041a0cfc2a2 1604 1603 2022-12-28T10:07:06Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] * Opcodes and instructions * Addressing modes * BIOS/System execution vs App/User execution ** ROM vs Flash instruction execution ** RAM System bank 0 vs App Bank 1 ** BIOS firmware calls * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual c1889d8509cce5cf7b2bbf9995dabcfa4b9a0b67 1605 1604 2022-12-28T10:07:28Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * BIOS/System execution vs App/User execution ** ROM vs Flash instruction execution ** RAM System bank 0 vs App Bank 1 ** BIOS firmware calls * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 62a72a71b4de0c1f8a710a026f10bec7b8a7a3fa 1606 1605 2022-12-28T10:08:24Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's hardware and peripherals can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * BIOS/System execution vs App/User execution ** ROM vs Flash instruction execution ** RAM System bank 0 vs App Bank 1 ** BIOS firmware calls * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 864f1e1b2b3dfc4be678eecd7a3e374061573cb1 1607 1606 2022-12-28T10:09:19Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * BIOS/System execution vs App/User execution ** ROM vs Flash instruction execution ** RAM System bank 0 vs App Bank 1 ** BIOS firmware calls * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 45ec46b426b405eedca17cecdf3fee30776eaa16 1608 1607 2022-12-28T10:10:10Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs Application Execution * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ed0240eb9f33f0fb792b6ef07675ead9944462ff 1609 1608 2022-12-28T10:13:15Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs Application Execution * Firmware built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ec073f6aee7737aa89e301ded66373d8c57baefe 1610 1609 2022-12-28T10:13:47Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs Application Execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 44f64d9acbed5610e62323aa37b9a3dc4c1aa41a 1611 1610 2022-12-28T10:18:24Z Unknown user 0 /* VMS Tetris */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs Application Execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual eee1d424e95315ed49fdb6bf22a1c8ebb58a9fdf 1612 1611 2022-12-28T10:19:47Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces.]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 451463bc26f70412d4f9e843c85ea0838f28a94b 1613 1612 2022-12-28T11:17:34Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 392887bfc42e819ec7c6a3658bb8279b00e1dfa5 VMU games 0 148 1597 461 2022-12-28T06:28:22Z Unknown user 0 wikitext text/x-wiki https://bswirl.kitsunet.org/vmu/game/ https://www.sega-dreamcast.com/specials/Dreamcast_VMU-MiniGames-Apps.htm {{DCWiki:Stub}} f910ed57624902f387ca1da27e0bb4bce3c277cc 1598 1597 2022-12-28T06:28:31Z Unknown user 0 wikitext text/x-wiki https://bswirl.kitsunet.org/vmu/game/<br> https://www.sega-dreamcast.com/specials/Dreamcast_VMU-MiniGames-Apps.htm {{DCWiki:Stub}} dbf914663a796bcda1b73988df46ef45aad679e9 Maple bus 0 113 1614 1568 2022-12-28T17:12:22Z Unknown user 0 /* Data Bits */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence [[File:Maple Bus Start Sequence.png|Maple Bus Start Sequence]] === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|Maple Bus End Sequence]] === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 1aefce02329d9de319fc2c4f49421f6f77fa787a 1615 1614 2022-12-28T17:13:02Z Unknown user 0 /* Start Sequence */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence === End Sequence === Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence [[File:Maple Bus End Sequence.png|Maple Bus End Sequence]] === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 4baf0290664e3188ddbc0b0265664c5d59d1c1de 1616 1615 2022-12-28T17:13:14Z Unknown user 0 /* End Sequence */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host [[File:Maple Bus Hardware Communication.png|Maple Bus Hardware Communication]] == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 2a3607211f32caa1346e5ec29258b385f64c8073 1617 1616 2022-12-28T17:17:13Z Unknown user 0 Playing with thumbnails to shrink diagrams which don't need to be on the forefront under text wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 88a5bb9594c0741fc3b4a9fe2a718ddaa92fc17d 1618 1617 2022-12-28T17:19:50Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 37056c7540f35d63dd7cf88d4d5e9dab7b7d9158 1624 1618 2022-12-28T18:04:38Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 681f4f45280a3225c2d9fa971950a938482d7a22 1625 1624 2022-12-28T18:15:35Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line **A** acts as clock and **B** acts as data for the first bit. Line **B** acts as clock and **A** acts as data for the next bit. Line **A** acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 94ccd0a9f7ab8e63f00c1774816bb3a7691863b2 1626 1625 2022-12-28T18:17:42Z Unknown user 0 changed bold characters to wiki markup instead of markdown wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. c91bf7d5aefc478e12bb5eeff8e1013c09253dfc 1627 1626 2022-12-28T18:19:44Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern (i.e. only one line may change states within each phase). On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 67721aa41197a25393d577d407d67eb1e31dec20 1628 1627 2022-12-28T18:21:36Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e. only one line may change its logic level within each phase. On the Dreamcast, each "phase" lasts about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases which is about 320 nanoseconds on the Dreamcast. Dreamcast controllers usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. 98844ef02af3a707b1b3589a55367fd05f579d67 1629 1628 2022-12-28T18:37:18Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bits === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e. only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3 word chunk after the first frame word. f58241a596acbfabaa9fd9a1f39f6c2e4ced9c3a 1630 1629 2022-12-28T21:12:30Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. ff3db5ae026fc45bb7680a0d2fe46ee7f594a32f 1632 1630 2022-12-28T21:59:35Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte === Frame Word === [[File:Frame Word.png|thumb|Frame Word Example]] The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} ==== Addressing ==== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ==== Commands ==== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [28](#device-info-payload-structure-cmd-0x05) || - |- | 0x06 || Extended Device Info || Device->Host || [48](#extended-device-info-payload-structure-cmd-0x06) || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [2..255](#data-transfer-payload-structure-cmd-0x08) || - |- | 0x09 || Get Condition || Host->Device || [1](#get-condition-payload-structure-cmd-0x09) || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [2](#get-memory-information-payload-structure-cmd-0x0a) || 0x08 |- | 0x0B || Block Read || Host->Device || [2](#block-read-payload-structure-cmd-0x0b) || 0x08 |- | 0x0C || Block Write || Host->Device || [3..255](#block-write-payload-structure-cmd-0x0c) || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || [2..255](#set-condition-payload-structure-cmd-0x0e) || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} *Most peripheral devices won't respond to any other command until device info is requested for the device. === Payload === The structure of a payload is structured based on the command used in the frame word. ==== Device Info Payload Structure (cmd 0x05) ==== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ==== Extended Device Info Payload Structure (cmd 0x06) ==== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ==== Data Transfer Payload Structure (cmd 0x08) ==== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ==== Get Condition Payload Structure (cmd 0x09) ==== {| class="wikitable" |- ! Word 0 |- | Function code |} ==== Get Memory Information Payload Structure (cmd 0x0A) ==== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ==== Block Read Payload Structure (cmd 0x0B) ==== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ==== Block Write Payload Structure (cmd 0x0C) ==== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ==== Get Last Error Payload Structure (cmd 0x0D) ==== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ==== Set Condition Payload Structure (cmd 0x0E) ==== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ==== Common Payload Word Types ==== ===== Function Codes ===== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ===== Location Word ===== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) === CRC === CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. fd2b0619f5de30fc7b19aa5c7ffa587585f603d1 1633 1632 2022-12-28T22:01:35Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte === Frame Word === The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ==== Addressing ==== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ==== Commands ==== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [28](#device-info-payload-structure-cmd-0x05) || - |- | 0x06 || Extended Device Info || Device->Host || [48](#extended-device-info-payload-structure-cmd-0x06) || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [2..255](#data-transfer-payload-structure-cmd-0x08) || - |- | 0x09 || Get Condition || Host->Device || [1](#get-condition-payload-structure-cmd-0x09) || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [2](#get-memory-information-payload-structure-cmd-0x0a) || 0x08 |- | 0x0B || Block Read || Host->Device || [2](#block-read-payload-structure-cmd-0x0b) || 0x08 |- | 0x0C || Block Write || Host->Device || [3..255](#block-write-payload-structure-cmd-0x0c) || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || [2..255](#set-condition-payload-structure-cmd-0x0e) || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} *Most peripheral devices won't respond to any other command until device info is requested for the device. === Payload === The structure of a payload is structured based on the command used in the frame word. ==== Device Info Payload Structure (cmd 0x05) ==== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ==== Extended Device Info Payload Structure (cmd 0x06) ==== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ==== Data Transfer Payload Structure (cmd 0x08) ==== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ==== Get Condition Payload Structure (cmd 0x09) ==== {| class="wikitable" |- ! Word 0 |- | Function code |} ==== Get Memory Information Payload Structure (cmd 0x0A) ==== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ==== Block Read Payload Structure (cmd 0x0B) ==== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ==== Block Write Payload Structure (cmd 0x0C) ==== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ==== Get Last Error Payload Structure (cmd 0x0D) ==== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ==== Set Condition Payload Structure (cmd 0x0E) ==== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ==== Common Payload Word Types ==== ===== Function Codes ===== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ===== Location Word ===== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) === CRC === CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. 4f869db016c9894b33bc670cb1c3e4f16a5f3146 1634 1633 2022-12-28T22:03:53Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [28](#device-info-payload-structure-cmd-0x05) || - |- | 0x06 || Extended Device Info || Device->Host || [48](#extended-device-info-payload-structure-cmd-0x06) || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [2..255](#data-transfer-payload-structure-cmd-0x08) || - |- | 0x09 || Get Condition || Host->Device || [1](#get-condition-payload-structure-cmd-0x09) || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [2](#get-memory-information-payload-structure-cmd-0x0a) || 0x08 |- | 0x0B || Block Read || Host->Device || [2](#block-read-payload-structure-cmd-0x0b) || 0x08 |- | 0x0C || Block Write || Host->Device || [3..255](#block-write-payload-structure-cmd-0x0c) || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || [2..255](#set-condition-payload-structure-cmd-0x0e) || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} *Most peripheral devices won't respond to any other command until device info is requested for the device. ==== Payload ==== The structure of a payload is structured based on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. 48f7063825c6bd8990d54335f8deb141503c351d 1635 1634 2022-12-28T22:04:42Z Unknown user 0 /* Common Payload Word Types */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [28](#device-info-payload-structure-cmd-0x05) || - |- | 0x06 || Extended Device Info || Device->Host || [48](#extended-device-info-payload-structure-cmd-0x06) || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [2..255](#data-transfer-payload-structure-cmd-0x08) || - |- | 0x09 || Get Condition || Host->Device || [1](#get-condition-payload-structure-cmd-0x09) || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [2](#get-memory-information-payload-structure-cmd-0x0a) || 0x08 |- | 0x0B || Block Read || Host->Device || [2](#block-read-payload-structure-cmd-0x0b) || 0x08 |- | 0x0C || Block Write || Host->Device || [3..255](#block-write-payload-structure-cmd-0x0c) || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || [2..255](#set-condition-payload-structure-cmd-0x0e) || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} *Most peripheral devices won't respond to any other command until device info is requested for the device. ==== Payload ==== The structure of a payload is structured based on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. 47c80c6e3ff6b56f4e69c687810a4b6c7ea94b74 1636 1635 2022-12-28T22:06:05Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} *Most peripheral devices won't respond to any other command until device info is requested for the device. ==== Payload ==== The structure of a payload is structured based on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. 9920d13c8d52b75c491e45a1689d02d5d04f591c File:Maple Bus Hardware Communication Neutral.png 6 714 1619 2022-12-28T17:24:38Z Unknown user 0 wikitext text/x-wiki Shows open communication line 92ab7adfb860e7f60097341892e513045c0d956b File:Maple Bus Hardware Communication Host Comm.png 6 715 1620 2022-12-28T17:25:21Z Unknown user 0 wikitext text/x-wiki Shows host communicating on Maple Bus 857ad94525d32b5b27af3c072d71449b38048531 File:Maple Bus Hardware Communication Device Comm.png 6 716 1621 2022-12-28T17:25:51Z Unknown user 0 wikitext text/x-wiki Shows device communicating on the Maple Bus d992289767df4cc1af2fe3fc78128834c501b964 File:Maple Bus Hardware Communication Vert Align.png 6 717 1622 2022-12-28T17:28:06Z Unknown user 0 wikitext text/x-wiki Shows how each device yields communication 10e32be9ab3561fcdeb3ff2c851644ef21ee5172 File:Dreamcast Port.png 6 718 1623 2022-12-28T18:03:57Z Unknown user 0 wikitext text/x-wiki Dreamcast Port 7739cb5653834d8a8aa0c4b2e58ef0557839ce3e File:Frame Word.png 6 719 1631 2022-12-28T21:30:33Z Unknown user 0 wikitext text/x-wiki Frame Word Example ea7c32550205abb6220890d29dfadc0283433d07 Maple bus 0 113 1637 1636 2022-12-28T22:08:33Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between one edge and the next on each line is the sum of the time of 2 phases. Dreamcast host transmits with each "phase" lasting about 160 nanoseconds which means each bit can be transmitted in about 480 nanoseconds. Dreamcast controllers and other peripheral devices usually transmit a little slower with each phase lasting about 250 nanoseconds with about 110 microsecond delays between each 3-word chunk after the first frame word. == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is structured based on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. 9366f13d2669708509ab37f3acb6ca85b632ea25 1640 1637 2022-12-28T23:28:58Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of another is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is structured based on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. bb6d5181bd5463299b8259ac4c5eabff228bf975 1641 1640 2022-12-28T23:35:26Z Unknown user 0 /* Maple Bus Signals */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is structured based on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. 89bdd1c4e59a5cefe4d0a408dd1451544ddcd3d1 1642 1641 2022-12-28T23:43:06Z Unknown user 0 /* Payload */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [word format](#word-format) section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. c8bce4fe0fd2feb228995286e30f251ba0fe7689 1643 1642 2022-12-28T23:43:54Z Unknown user 0 /* Payload */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a source address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its source address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. c2b534bb5e75bd19073b146198ff7146e9ae88d2 1644 1643 2022-12-28T23:49:48Z Unknown user 0 /* Addressing */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL. [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. e625e8118090d2b30a7b76f4c01be4a748fd4d4f 1646 1644 2022-12-29T01:35:14Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref>{{cite web|author=Raphaël Assenat|title=Dreamcast controller to USB build log|url=https://www.raphnet.net/programmation/dreamcast_usb/index_en.php}}</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == {{Reflist}} 6f2ac8c75031619b4e893ce46caa2cefa5509f7c 1650 1646 2022-12-29T01:40:12Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref>{{cite web|author=Raphaël Assenat|title=Dreamcast controller to USB build log|url=https://www.raphnet.net/programmation/dreamcast_usb/index_en.php}}</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> c64d07ab56fd85f9b837d6a57f45845afb5fd38e 1651 1650 2022-12-29T01:43:12Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus. Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref>''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php], Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> e541ee020e53a4141faab4ff384dd8b464ccbedd 1652 1651 2022-12-29T02:22:19Z Unknown user 0 Added references wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref>''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below.{{Citation needed}} === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds{{Citation needed}} ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word{{Citation needed}} ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> b7275436bf79b5aab4e708d7dfdcb7fcbfc24ff4 1653 1652 2022-12-29T02:58:25Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><refname="raphnet" /><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the [[File:Dreamcast_controller_board_rear_view.png|controller port module]]. Instead, Dreamcast polls for device info every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below.{{Citation needed}} === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds{{Citation needed}} ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word{{Citation needed}} ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 6db585bdf4fe49e81eeab286cd5401bfb75bfdae 1654 1653 2022-12-29T03:00:48Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref name="raphnet" /><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. Instead, Dreamcast polls for device info every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below.{{Citation needed}} === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds{{Citation needed}} ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word{{Citation needed}} ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 80c2e493456181e58d592404c70c6d6b612a4911 1655 1654 2022-12-29T03:01:24Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. Instead, Dreamcast polls for device info every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below.{{Citation needed}} === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds{{Citation needed}} ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word{{Citation needed}} ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8245707b8205ad54929a6c5cf6d5e89d77ab7a8c 1656 1655 2022-12-29T03:02:33Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below.{{Citation needed}} === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds{{Citation needed}} ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word{{Citation needed}} ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> e762fb09232b0e8a42724012cc8c06828fbce0c6 1657 1656 2022-12-29T03:47:15Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds. There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico''</ref> === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> e195e034e90ba8b38b4e3554c72a822df603ac6b 1658 1657 2022-12-29T03:48:00Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 35d0ce60662cf6b653a8965d9be78971a8aaf47e 1659 1658 2022-12-29T03:48:36Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each state transition can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> cc1f935968270761ccc19b807285323524500599 1660 1659 2022-12-29T04:24:54Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> fd04af39292d76b4fb8e3a3d8874d58f70226453 1661 1660 2022-12-29T16:58:14Z Unknown user 0 /* Maple Bus Signals */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|Maple Bus Electronics Block Diagram]] [[File:Maple Bus Hardware Communication.png|thumb|Maple Bus Hardware Communication]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 740c554d08392adc55d1c88dd9e4e8d0a3f3ac15 1667 1661 2022-12-29T17:29:48Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Hardware Communication.png|thumb|500px|Maple Bus Hardware Communication]] [[File:Maple Bus Electronics Block Diagram2.png|frameless|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> d156be6c010632ec79c9621756ffb9769c3fe0f9 1668 1667 2022-12-29T17:38:13Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram2.png|frameless|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|500px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> a477e1c525bf056d2d920e5570b198aafae582ad 1677 1668 2022-12-29T19:36:11Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] A Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> bc2d241201726d6ae2ff8fc59a366c8849feebe8 1679 1677 2022-12-29T19:43:27Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || 28 || - |- | 0x06 || Extended Device Info || Device->Host || 48 || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || 2..255 || - |- | 0x09 || Get Condition || Host->Device || 1 || 0x08 |- | 0x0A || Get Memory Information || Host->Device || 2 || 0x08 |- | 0x0B || Block Read || Host->Device || 2 || 0x08 |- | 0x0C || Block Write || Host->Device || 3..255 || 0x07 |- | 0x0D || Get Last Error || Host->Device || 2 || 0x07 |- | 0x0E || Set Condition || Host->Device || 2..255 || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || Function Code Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported function codes mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | Function code |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | Function code || Location word || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | Function code || Location word |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | Function code || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8f92c850992db5407b5ae8921048fba2406076d1 1680 1679 2022-12-29T19:56:52Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''Frame:''' 1 32-Bit Word * '''Payload:''' 0 to 255 32-Bit Words * '''CRC:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>Address</div> || <div style="text-align: center;">Recipient<br>Address</div> || <div style="text-align: center;">Command</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 40ab1a444dd3f4a949ad87e5c4342158129aaf18 1681 1680 2022-12-29T19:59:08Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> aa325f31e14d3092c9dce52615bd78880de8aad2 Development 0 2 1638 1586 2022-12-28T22:23:42Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 681dc463b10e23c83474f59a6e189b1f2acdf220 Dreamcast.wiki 0 1 1639 816 2022-12-28T23:05:54Z Unknown user 0 /* How To */ wikitext text/x-wiki [[File:Dreamcast.jpg|500px|thumb|right|The Sega Dreamcast in all its glory]] {{DCWiki:About}} == How To == * Identify a [[MIL-CD compatibility|MIL-CD compatible console]] to ensure your console is capable of booting CD-ROM and CD-R media * Create a [[Creating a bootable Dreamcast disc|bootable Dreamcast disc]] -- Dreamcast requires no modchip or hardware modification! * Play [[Playing import games|import games]] * Dump [[Dumping GD-ROMs|original GD-ROM discs]] * Connect to a [[Modern A/V guide|modern television or display]] * Get started with [[Getting Started with Dreamcast development|Dreamcast development]] {{DCWiki:Software}} {{DCWiki:Hardware}} __NOTOC__ {{DISPLAYTITLE:dreamcast.wiki}} 01d36ae64122b1d6cd0ebae8cef69f6f094b23de Template:Cite web 10 720 1645 2022-12-29T01:33:39Z Unknown user 0 Created page with "<includeonly>{{#invoke:citation/CS1|citation |CitationClass=web }}</includeonly><noinclude> {{documentation}} </noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:citation/CS1|citation |CitationClass=web }}</includeonly><noinclude> {{documentation}} </noinclude> ea1b0f38afd9728a1cf9f2e3f540887a402fab8e Template:Reflist 10 721 1647 2022-12-29T01:35:41Z Unknown user 0 Created page with "<templatestyles src="Reflist/styles.css" /><div class="reflist <!-- -->{{#if:{{{1|}}}{{{colwidth|}}}|reflist-columns references-column-width}} <!-- -->{{#switch:{{{liststyle|{..." wikitext text/x-wiki <templatestyles src="Reflist/styles.css" /><div class="reflist <!-- -->{{#if:{{{1|}}}{{{colwidth|}}}|reflist-columns references-column-width}} <!-- -->{{#switch:{{{liststyle|{{{group|}}}}}}|upper-alpha|upper-roman|lower-alpha|lower-greek|lower-roman=reflist-{{{liststyle|{{{group}}}}}}}} <!-- -->{{#if:{{{1|}}}|{{#iferror:{{#ifexpr: {{{1|1}}} > 1 }}||{{#switch:{{{1|}}}|1=|2=reflist-columns-2|#default=reflist-columns-3}} }}}}" <!-- end class -->{{#if: {{{1|}}}<!-- start style --> | {{#iferror: {{#ifexpr: {{{1|1}}} > 1 }} |style="column-width: {{{1}}};"}} | {{#if: {{{colwidth|}}}|style="column-width: {{{colwidth}}};"}} }}> {{#tag:references|{{{refs|}}}|group={{{group|}}}|responsive={{#if:{{{1|}}}{{{colwidth|}}}|0|1}}}}</div>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using reflist with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Reflist]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | colwidth | group | liststyle | refs }}<noinclude> {{Documentation}} </noinclude> 8c65cc88272db6c0f5cf2b49f84d3e460e60ee5f Template:Documentation 10 722 1648 2022-12-29T01:36:55Z Unknown user 0 Created page with "{{#invoke:documentation|main|_content={{ {{#invoke:documentation|contentTitle}}}}}}<noinclude> <!-- Add categories to the /doc subpage --> </noinclude>" wikitext text/x-wiki {{#invoke:documentation|main|_content={{ {{#invoke:documentation|contentTitle}}}}}}<noinclude> <!-- Add categories to the /doc subpage --> </noinclude> 9e62b964e96c4e3d478edecbfcb3c0338ae8a276 Template:Main other 10 723 1649 2022-12-29T01:37:47Z Unknown user 0 Created page with "{{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> |..." wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | other }} }} | main = {{{1|}}} | other | #default = {{{2|}}} }}<noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude> 86ad907ffeea3cc545159e00cd1f2d6433946450 File:Maple Bus Electronics Block Diagram.png 6 700 1662 1556 2022-12-29T17:19:37Z Unknown user 0 Tails86 uploaded a new version of [[File:Maple Bus Electronics Block Diagram.png]] wikitext text/x-wiki Depicts how host and devices are physically connected to the bus a5a7999b149da66ad8d7a0695918704e8f03688d 1663 1662 2022-12-29T17:21:51Z Unknown user 0 Tails86 reverted [[File:Maple Bus Electronics Block Diagram.png]] to an old version wikitext text/x-wiki Depicts how host and devices are physically connected to the bus a5a7999b149da66ad8d7a0695918704e8f03688d 1664 1663 2022-12-29T17:22:11Z Unknown user 0 Tails86 reverted [[File:Maple Bus Electronics Block Diagram.png]] to an old version wikitext text/x-wiki Depicts how host and devices are physically connected to the bus a5a7999b149da66ad8d7a0695918704e8f03688d 1665 1664 2022-12-29T17:22:45Z Unknown user 0 Tails86 reverted [[File:Maple Bus Electronics Block Diagram.png]] to an old version wikitext text/x-wiki Depicts how host and devices are physically connected to the bus a5a7999b149da66ad8d7a0695918704e8f03688d 1670 1665 2022-12-29T18:45:45Z Unknown user 0 Tails86 reverted [[File:Maple Bus Electronics Block Diagram.png]] to an old version wikitext text/x-wiki Depicts how host and devices are physically connected to the bus a5a7999b149da66ad8d7a0695918704e8f03688d File:Maple Bus Hardware Communication.png 6 701 1669 1557 2022-12-29T18:33:43Z Unknown user 0 Tails86 uploaded a new version of [[File:Maple Bus Hardware Communication.png]] wikitext text/x-wiki Depicts how the bus is shared for communication between host and devices b8ca60e87c62d611bde5ba0ca459003838a03e9b VMU development 0 99 1671 1613 2022-12-29T19:10:45Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you're have any questions or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://mcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/TYsvK9t Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear and ElysianVMU === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual db9e8d33a72b0ec5ca9022f0cdb4b6849d40f203 1672 1671 2022-12-29T19:12:23Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you're have any questions or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://mcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual d7dc55dc6901b80438a674fa3aa9901a5c7a479f 1673 1672 2022-12-29T19:16:16Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you're have any questions or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 33aae287519c043b15c3dad6de60ddf746a4bcfe 1675 1673 2022-12-29T19:18:51Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual f4377d9f1460d30ec6d8e6ce98e2df8a4d8bdf90 DCWiki:About 4 80 1674 241 2022-12-29T19:17:39Z Unknown user 0 wikitext text/x-wiki dreamcast.wiki is a new compendium of Dreamcast-related knowledge launched in 2020. The Sega Dreamcast was the last new video game console to be manufactured by Sega. First sold in Japan in 1998, the console was widely considered ahead of its time due to its advanced graphics and built-in online connectivity. When it became possible to run custom code from CD-R with no hardware modifications or hacks necessary in 2000, the online Dreamcast homebrew scene exploded and created homebrew libraries, SDKs, freeware games and ports of fans' favorite games, emulators for vintage game consoles and computers, utilities, media players, and more. The console has gained a huge following worldwide, with enthusiast scenes thriving in many languages. Starting with Feet of Fury in 2003, dozens of independent game titles have been developed and sold on the Dreamcast with more on the horizon for 2020 and beyond. Hardware hackers have taken the console into a new era with SD, USB, and hard drive storage capabilities and HDMI video. The Dream will never die, and we aim to be its knowledge base. Want to contribute? Signups were open, until the spambots invaded. Register on the [https://dcemulation.org/phpBB/index.php message board] and send a [https://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=5284 private message] for access! 5ec245378bd811a4eea8cf51a88a83dff1386107 MediaWiki:Simulant-discord-url 8 26 1676 78 2022-12-29T19:19:43Z Unknown user 0 wikitext text/x-wiki https://discord.gg/bpDZHT78PA 0b1e007809c083593664299f2a16b60070b8f000 File:Maple Bus End Sequence.png 6 703 1682 1559 2022-12-29T20:20:53Z Unknown user 0 Tails86 uploaded a new version of [[File:Maple Bus End Sequence.png]] wikitext text/x-wiki Shows the signals which complete a packet transmission 9435d8d99ac76128933f23622173a015f614b348 File:Dreamcast Screen Words.png 6 725 1683 2022-12-30T00:27:29Z Unknown user 0 wikitext text/x-wiki Dreamcast Screen Words 55f454768abf09be3f2f598bad62fd09156a2c8d VMU peripheral 0 726 1684 2022-12-30T00:28:19Z Unknown user 0 Created page with "The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. === Screen === The "block write" command (0x0C) with screen function code..." wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. === Screen === The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] === Storage === The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write the 256 blocks of memory in the storage peripheral. There are 256 pages of memory that make up the entire storage space. Each page consists of 512 bytes. That makes a total of 128 KB of memory. === Timer === The timer function allows the host to activate the buzzer on the VMU and get button conditions. f03ae744b80cbcb8d97d127508121fa219eb11d7 VMU 0 137 1685 1596 2022-12-30T00:28:47Z Unknown user 0 wikitext text/x-wiki * [[VMU_hardware_overview|Hardware Overview]] * [[VMU_games|Games]] * [[VMU_development|Development]] * [[VMU_emulators|Emulators]] * [[VMU_mods|Modifications]] * [[VMU_peripheral|Peripheral]] {{DCWiki:Stub}} 763352a69a843e99d79284417c91caa4609a01f6 Controller peripheral 0 727 1686 2022-12-30T00:48:16Z Unknown user 0 Created page with "The controller acts as a main peripheral device on the [[Maple_bus|Maple Bus]]. == Controller == The "get condition" command (0x09) with controller function code is used to..." wikitext text/x-wiki The controller acts as a main peripheral device on the [[Maple_bus|Maple Bus]]. == Controller == The "get condition" command (0x09) with controller function code is used to poll controller state. A "data transfer" command (0x08) is returned with controller function code word plus 2 words of data. The returned data must be parsed differently depending on the function definition for the controller. The below sections show how to parse data for a standard controller. === First Data Transfer Word === All button bits are 0 when pressed and 1 when released. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Left analog trigger 0 to 255<br>0: fully released<br>255: fully pressed || Right analog trigger 0 to 255<br>0: fully released<br>255: fully pressed || Button bits<br>0x01: Z<br>0x02: Y<br>0x04: X || Button bits<br>0x01: C<br>0x02: B<br>0x04: A<br>0x08: Start<br>0x10: Up<br>0x20: Down<br>0x40: Left<br>0x80: Right |} === Second Data Transfer Word === {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Right analog stick up/down<br>Always 128<br>(no controller uses this) || Right analog stick left/right<br>Always 128<br>(no controller uses this) || Left analog up/down<br>0: fully up<br>128: center<br>255: fully down || Left analog left/right<br>0: fully left<br>128: center<br>255: fully right |} 98deba25b16d4394de301760e7ac43ea5084f34a Controller 0 728 1687 2022-12-30T00:48:54Z Unknown user 0 Created page with "* [[Controller_peripheral|Peripheral]]" wikitext text/x-wiki * [[Controller_peripheral|Peripheral]] cacc0775c273d198af0334de5121368063657619 Jump pack peripheral 0 729 1688 2022-12-30T00:58:31Z Unknown user 0 Created page with "The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set con..." wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | 0 || 0 || 0 || 1 || 0 || 0 || 0 || X |} Bit 0 may be set to 1 to augment duration, but the meaning is not completely understood. As such, that bit is always set to 0 for this implementation. fed96f58afe13ddfbd089df41cb0b509e5703cff Jump pack 0 730 1689 2022-12-30T00:58:56Z Unknown user 0 Created page with "[[Jump pack peripheral|Peripheral]]" wikitext text/x-wiki [[Jump pack peripheral|Peripheral]] 7d1af3cfd3bc1b37f7869098bfcc1a46ebfca4f4 Controller peripheral 0 727 1690 1686 2022-12-30T00:59:18Z Unknown user 0 wikitext text/x-wiki The controller acts as a main peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Controller == The "get condition" command (0x09) with controller function code is used to poll controller state. A "data transfer" command (0x08) is returned with controller function code word plus 2 words of data. The returned data must be parsed differently depending on the function definition for the controller. The below sections show how to parse data for a standard controller. === First Data Transfer Word === All button bits are 0 when pressed and 1 when released. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Left analog trigger 0 to 255<br>0: fully released<br>255: fully pressed || Right analog trigger 0 to 255<br>0: fully released<br>255: fully pressed || Button bits<br>0x01: Z<br>0x02: Y<br>0x04: X || Button bits<br>0x01: C<br>0x02: B<br>0x04: A<br>0x08: Start<br>0x10: Up<br>0x20: Down<br>0x40: Left<br>0x80: Right |} === Second Data Transfer Word === {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Right analog stick up/down<br>Always 128<br>(no controller uses this) || Right analog stick left/right<br>Always 128<br>(no controller uses this) || Left analog up/down<br>0: fully up<br>128: center<br>255: fully down || Left analog left/right<br>0: fully left<br>128: center<br>255: fully right |} 867ae89988c79d24464e1dfe0e74371a3760540b VMU peripheral 0 726 1691 1684 2022-12-30T00:59:34Z Unknown user 0 wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete === Screen === The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] === Storage === The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write the 256 blocks of memory in the storage peripheral. There are 256 pages of memory that make up the entire storage space. Each page consists of 512 bytes. That makes a total of 128 KB of memory. === Timer === The timer function allows the host to activate the buzzer on the VMU and get button conditions. 29c0eaf9a19e77a795f32dfffc66b84c689c7738 1731 1691 2023-01-01T06:36:35Z Unknown user 0 wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete === Screen === The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] === Storage === The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> ==== Function Definition ==== The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block (x + 1)*32 || number of partitions |} ==== Block Read ==== Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. ==== Block Write ==== Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * If any block write fails, it is necessary to send "get last error" before starting over at the first write sequence. * A VMU cannot handle successive block write packets faster than about 10 ms. If writing too fast, the response of "get last error" will be "file error". === Timer === The timer function allows the host to activate the buzzer on the VMU and get button conditions. 2c06d258ffeabca092ef388a41242f294ba9d10c 1732 1731 2023-01-01T06:37:21Z Unknown user 0 /* Function Definition */ wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete === Screen === The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] === Storage === The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> ==== Function Definition ==== The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions |} ==== Block Read ==== Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. ==== Block Write ==== Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * If any block write fails, it is necessary to send "get last error" before starting over at the first write sequence. * A VMU cannot handle successive block write packets faster than about 10 ms. If writing too fast, the response of "get last error" will be "file error". === Timer === The timer function allows the host to activate the buzzer on the VMU and get button conditions. 86cbb9d5e4b92daf8bea6ef687adde9e2cb9f8b0 1733 1732 2023-01-01T06:38:20Z Unknown user 0 wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete === Screen === The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] === Storage === The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> ==== Function Definition ==== The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions |} ==== Block Read ==== Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. ==== Block Write ==== Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * If any block write fails, it is necessary to send "get last error" before starting over at the first write sequence. * A VMU cannot handle successive block write packets faster than about 10 ms. If writing too fast, the response of "get last error" will be "file error". === Timer === The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> 5132b1b0f74ea46c3af254b7a2686e2653fae6fa 1734 1733 2023-01-01T06:39:38Z Unknown user 0 wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * If any block write fails, it is necessary to send "get last error" before starting over at the first write sequence. * A VMU cannot handle successive block write packets faster than about 10 ms. If writing too fast, the response of "get last error" will be "file error". == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> 4d018e1c99e749e2d1d68258d868620b702cfa99 1735 1734 2023-01-01T06:48:50Z Unknown user 0 wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * A VMU cannot handle successive block write packets faster than about 10 ms per write. If writing too fast, no response may be seen. ** After such error, the storage functionality acts as if it never received this sequence - it may be possible to resend this sequence, but writing a "get last error" command would be necessary before starting over at the first sequence == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> b33238bdf14310dea4e510d0ebfbff19eb29d290 1736 1735 2023-01-01T06:52:45Z Unknown user 0 /* Block Write */ wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * A VMU cannot handle successive block write packets faster than about 10 ms per write ** After such error, the storage functionality acts as if it never received this sequence and never returns a response packet - it may be possible to successfully resend this sequence, but writing a "get last error" command would be necessary before starting over at the first sequence == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> bbe67152ec741e28133810cb808ec2f5811649bc File:SH GCC in Compiler Explorer.png 6 731 1692 2022-12-30T05:06:29Z Unknown user 0 wikitext text/x-wiki Selecting a GCC version of the SH cross-compiler 8e74353cd0afbcc333614b5ba0b39ddd6b6cfcfd File:SH GCC Compiler Explorer.png 6 732 1693 2022-12-30T05:11:11Z Unknown user 0 wikitext text/x-wiki Dreamcast-like SH GCC Compiler Configuration 337d4603983ba0a5b513104b61c0cca4d65d0521 SH4 in Compiler Explorer 0 733 1694 2022-12-30T05:35:41Z Unknown user 0 Created page with "Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt...." wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode. * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic. * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 (supposedly the highest, although the SH compiler does seem to generate different code in certain circumstances when going higher) * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred. * The compiler does not seem start enough to utilize the FIPR (inner product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. f1c1cc097a38df735e6c03608b224ba95682c7d0 1695 1694 2022-12-30T05:37:45Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode. * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic. * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. 8f9ab5a42095438bafae869cbf963caa68f7cd75 1696 1695 2022-12-30T05:38:26Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode. * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic. * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code is seen with newer versions of GCC versus the older ones; however, this is not always the case. 9fe234bb9902556c624f2fd1888ddcdb2776631e 1697 1696 2022-12-30T05:39:05Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode. * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic. * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code is seen with newer versions of GCC versus the older ones; however, this is not always the case. 1194e9834bbdbb88fc2ee07a20ba3242e6fd48d8 1700 1697 2022-12-30T05:41:39Z Unknown user 0 /* Tips and Notes */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode. * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic. * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code is seen with newer versions of GCC versus the older ones; however, this is not always the case. da7654f63106aabe4eff5cdeb63fe4edb89f360d 1701 1700 2022-12-30T05:42:10Z Unknown user 0 /* Tips and Notes */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode. * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic. * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. c2af04098381fe16edc71a37fe1d006cccf65a02 1702 1701 2022-12-30T05:42:56Z Unknown user 0 /* Configuration */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH GCC Compiler Explorer.png|thumb|Dreamcast-like SuperH GCC Compiler Configuration]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. 537069cfbb27f502a881b1631814be3279140fb8 1704 1702 2022-12-30T06:00:09Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. efecca251150f6fc0816d9df4b1999d6ec792a1a Development 0 2 1698 1638 2022-12-30T05:39:41Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[Editing SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] bab60df3baba5a419baa35df71e4d7ef66d5fa4a 1699 1698 2022-12-30T05:40:03Z Unknown user 0 /* Optimization */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 4c012ce0c31d1f2b26aa5bb0ad278e7ed7e557ba File:SH4 Compiler Explorer Configuration.png 6 734 1703 2022-12-30T05:59:34Z Unknown user 0 wikitext text/x-wiki SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer 132b1a90b5c17f646c3dfb3f62b323d4c126c81e File:Serial Pads.png 6 735 1705 2022-12-30T06:18:07Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dreamcast motherboard with serial pads identified}} |date=2022-12-30 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 77b92cfe0119b149f001160d74a25b4a169aaad9 File:Serial Pinout.png 6 736 1706 2022-12-30T06:29:07Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Photo of Serial Connector on PCB with Pins Labeled}} |date=2022-12-30 |source={{own}} |author=[[User:Colton|Colton]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b80e8eb580bec7227dbf31e54683927d385dea7d Serial interface 0 93 1707 356 2022-12-30T06:34:59Z Unknown user 0 wikitext text/x-wiki The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. [[File:Serial Pinout.png|thumb|PCB Serial Port with Labeled Pins]] {| class="wikitable" |+Serial connector pinout |- ! Pin ! Description |- |1 | +5V |- |2 |SCK |- |3 |Ground |- |4 |RX2 |- |5 |TX2 |- |6 |RTS |- |7 |CTS |- |8 |Ground |- |9 |Reset |- |10 | +3.3V |} [[File:Serial Pads.png|thumb|Serial Connection Pinout for Test Points on Bottom of Board]] A SCIF loopback connection can be created to allow a Dreamcast to conduct and pass the SCIF test on the official Sega [[DC Checker]] diagnostics software by connecting pin 4 (RX2) to pin 5 (TXD) and connecting pin 6 (RTS) to pin 7 (CTS). {{DCWiki:Stub}} 982a4ad722813ffe3163dd8ec9880bc8c16995e7 DCWiki:Software 4 81 1708 845 2022-12-30T17:58:27Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * [[Online Services]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[VMU development]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[Useful programming tips]] |} |} 73d38f411bda6ca84f3ad9bc6ef56543fef827f1 File:Scrolling Text Tech Demo.zip 6 737 1709 2022-12-30T20:45:03Z Unknown user 0 wikitext text/x-wiki Tech Demonstration source code for scrolling text on the VMU ff5ac08b495b850358834f661d9a5bd258354b97 File:Skeleton VMU Application.zip 6 738 1710 2022-12-30T20:48:05Z Unknown user 0 wikitext text/x-wiki Source code for a skeleton VMU app be141fa0decf2399b5e80541664defdcea806651 VMU development 0 99 1711 1675 2022-12-30T20:49:03Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip|thumb]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 7761a7bf366c10e2b6ed92e0e18df04f4d1136cf 1713 1711 2022-12-30T21:21:46Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio fro the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 0df6a8cdf4b14d6be298caed637722b49e3378e5 1714 1713 2022-12-30T21:23:06Z Unknown user 0 /* Official Demos */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== VMU Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual e5e056adf1f4d904e55993b6025d0f8ef20d9572 1717 1714 2022-12-31T05:43:55Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ced65a5c641415824ab6d55d59fd5b755c7e3b5d 1718 1717 2022-12-31T05:46:26Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmu Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [http://dreamcast-talk.com/forum/index.php Dreamcast-Talk Forums] - A popular Dreamcast gaming and homebrew enthusiast forum * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual cd266e52b3c15184fb2a706e822df9c88db7d578 File:VMU Development Resources.zip 6 739 1712 2022-12-30T21:19:51Z Unknown user 0 wikitext text/x-wiki Compilation of assorted development resources and demos 98336ab848d97094edc31b6834e9022fa60485e6 1737 1712 2023-01-01T06:59:46Z Unknown user 0 GyroVorbis uploaded a new version of [[File:VMU Development Resources.gz]] wikitext text/x-wiki Compilation of assorted development resources and demos 98336ab848d97094edc31b6834e9022fa60485e6 1738 1737 2023-01-01T07:00:57Z Unknown user 0 GyroVorbis moved page [[File:VMU Development Resources.gz]] to [[File:VMU Development Resources.zip]] wikitext text/x-wiki Compilation of assorted development resources and demos 98336ab848d97094edc31b6834e9022fa60485e6 32MB RAM expansion 0 284 1715 1532 2022-12-31T04:20:04Z Unknown user 0 /* KallistiOS */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/amx3-32mb fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b 32mb-mk2 https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d kilobytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The hardware_memsize() function can be called to retrieve the running system's size */ printf("hardware_memsize() reports this system has %d kilobytes.\n", hardware_memsize()); printf("This is a %s console!\n", (hardware_memsize() == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* mm_top() can be used to get the top address of memory */ printf("Top of memory is 0x%0x!\n", mm_top()); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X f7dc1c449e15ffa0a43410b7441f665bb735c906 File:Dream Animator.jpg 6 740 1716 2022-12-31T05:42:44Z Unknown user 0 wikitext text/x-wiki Screenshot of the old Dream Animator VMU animation tool d8e456ee0a440619b2dfc66391fc025227b87a06 File:Yellowed Dreamcast.jpg 6 741 1719 2022-12-31T15:01:30Z Unknown user 0 wikitext text/x-wiki Picture of a yellowed Dreamcast 892d8d1afc741ff9b8a444eff77397d340997fbd File:Whitened Dreamcast.jpg 6 742 1720 2022-12-31T15:02:58Z Unknown user 0 wikitext text/x-wiki A picture of the yellowed Dreamcast after it was whitened with Retro-Brite 86d55dd88c12eb3193501b8c74679c4caf289e5f Case whitening 0 743 1721 2022-12-31T15:15:31Z Unknown user 0 Created page with "The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Retro-Brite == [https://www.amazon.com/Retro-Brite-Sole-Sauce-..." wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Retro-Brite == [https://www.amazon.com/Retro-Brite-Sole-Sauce-Restores-Yellowed/dp/B08668347P Retro-Brite] is a spray-on gel. Do the following to whiten using this product: # Disassemble the plastic case into the bottom shell, top shell, CD lid, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid # Put on gloves and spray down every exposed surface of all of the plastic pieces # Put each plastic piece into one or more plastic bags so that the yellowed surfaces are all visible from one side of the bag # Leave the bag(s) in full sun or under a UV light for 8 to 24 hours, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # Reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> 4c716725b80efa72109d61128ceb3f92b0fa5e9c 1722 1721 2022-12-31T15:16:12Z Unknown user 0 Use official retro-brite website wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Retro-Brite == [https://retro-brite.com/ Retro-Brite] is a spray-on gel. Do the following to whiten using this product: # Disassemble the plastic case into the bottom shell, top shell, CD lid, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid # Put on gloves and spray down every exposed surface of all of the plastic pieces # Put each plastic piece into one or more plastic bags so that the yellowed surfaces are all visible from one side of the bag # Leave the bag(s) in full sun or under a UV light for 8 to 24 hours, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # Reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> c0dc625c9b5c56450f839264aeeb9564712fb512 1723 1722 2022-12-31T15:23:56Z Unknown user 0 wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Retro-Brite == [https://retro-brite.com/ Retro-Brite] is a spray-on gel. Do the following to whiten using this product: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid # Put on gloves and spray down every exposed surface of all of the plastic pieces # Put each plastic piece into one or more plastic bags so that the yellowed surfaces are all visible from one side of the bag # Leave the bag(s) in full sun or under a UV light for 8 to 24 hours, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # Reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> 88ff191a68cce55d8ab8729540bc5ea1e700856c Maracas 0 744 1724 2022-12-31T20:48:22Z Unknown user 0 Created page with "= Maple Protocol = The Maracas peripheral implements the "FT0 (Controller)" function, meaning that its functionality is mapped to the various buttons and analog axes of a regu..." wikitext text/x-wiki = Maple Protocol = The Maracas peripheral implements the "FT0 (Controller)" function, meaning that its functionality is mapped to the various buttons and analog axes of a regular controller. == Button Mapping == {| class="wikitable" |- ! Operation !! Left Maraca !! Right Maraca |- | Position || Analog Axis A || Analog Axis B |- | Shake || B || A |- | Button || C || Start |- | Connection Loss || D || Z |} == Initialization == Upon reset, the maracas begin performing ultrasonic wave emission timing adjustment. During this process, button input is disabled, their positions remains fixed, and the connection loss signal is active. The following table dictates the duration of this period. {| class="wikitable" |- ! Port !! Seconds !! # of "Get Condition" queries |- | A || 4 || 240 |- | B || 5 || 300 |- | C || 6 || 360 |- | D || 7 || 420 |} 4123338d6672bef43b7f3a0823a0457d15f810bc 1725 1724 2022-12-31T20:51:19Z Unknown user 0 wikitext text/x-wiki = Maple Protocol = The Maracas peripheral implements the "FT0 (Controller)" function, meaning that its functionality is mapped to the various buttons and analog axes of a regular controller. == Button Mapping == {| class="wikitable" |- ! Operation !! Left Maraca !! Right Maraca |- | Position || Analog Axis A || Analog Axis B |- | Shake || B || A |- | Button || C || Start |- | Connection Loss || D || Z |} == Initialization == Upon reset, the maracas begin performing ultrasonic wave emission timing adjustment. During this process, button input is disabled, their positions remains fixed, and the connection loss signal is active. The following table dictates the duration of this period. {| class="wikitable" |- ! Port !! Seconds !! # of "Get Condition" queries |- | A || 4 || 240 |- | B || 5 || 300 |- | C || 6 || 360 |- | D || 7 || 420 |} ''Note: evidently the timing adjustments for multiple maracas are still not guaranteed to succeed despite this initialization period. In such a scenario, additional software is required to manually make the adjustments.'' 787a07b681ff41f024af0705e1d46df3638d9d5e 1727 1725 2022-12-31T20:58:45Z Unknown user 0 wikitext text/x-wiki [[File:Samba De Amigo Maracas.jpg|thumb|Samba De Amigo Maracas, including box, mat, and ultrasonic receiver.]] The maracas are a peripheral for the Sega Dreamcast which were used with the Latin-Themed dance rhythm game [[Samba De Amigo]]. They feature an ultrasonic sensor for positional tracking within 3D space along with sensors to detect when they are being shaked. = Maple Protocol = The Maracas peripheral implements the "FT0 (Controller)" function, meaning that its functionality is mapped to the various buttons and analog axes of a regular controller. == Button Mapping == {| class="wikitable" |- ! Operation !! Left Maraca !! Right Maraca |- | Position || Analog Axis A || Analog Axis B |- | Shake || B || A |- | Button || C || Start |- | Connection Loss || D || Z |} == Initialization == Upon reset, the maracas begin performing ultrasonic wave emission timing adjustment. During this process, button input is disabled, their positions remains fixed, and the connection loss signal is active. The following table dictates the duration of this period. {| class="wikitable" |- ! Port !! Seconds !! # of "Get Condition" queries |- | A || 4 || 240 |- | B || 5 || 300 |- | C || 6 || 360 |- | D || 7 || 420 |} ''Note: evidently the timing adjustments for multiple maracas are still not guaranteed to succeed despite this initialization period. In such a scenario, additional software is required to manually make the adjustments.'' dc9d1531d43debd3d8ad54a6670d134e2eb4968a 1729 1727 2022-12-31T21:01:20Z Unknown user 0 wikitext text/x-wiki [[File:Samba De Amigo Maracas.jpg|thumb|Samba De Amigo Maracas, including box, mat, and ultrasonic receiver.]] The maracas are a peripheral for the Sega Dreamcast which were used with the Latin-Themed dance rhythm game [[Samba De Amigo]]. They feature an ultrasonic sensor for positional tracking within 3D space along with sensors to detect when they are being shaked. [[File:Cha Cha Amigo Maracas.jpg|thumb|3rd Party "Cha Cha Amigo" Maracas ]] = Maple Protocol = The Maracas peripheral implements the "FT0 (Controller)" function, meaning that its functionality is mapped to the various buttons and analog axes of a regular controller. == Button Mapping == {| class="wikitable" |- ! Operation !! Left Maraca !! Right Maraca |- | Position || Analog Axis A || Analog Axis B |- | Shake || B || A |- | Button || C || Start |- | Connection Loss || D || Z |} == Initialization == Upon reset, the maracas begin performing ultrasonic wave emission timing adjustment. During this process, button input is disabled, their positions remains fixed, and the connection loss signal is active. The following table dictates the duration of this period. {| class="wikitable" |- ! Port !! Seconds !! # of "Get Condition" queries |- | A || 4 || 240 |- | B || 5 || 300 |- | C || 6 || 360 |- | D || 7 || 420 |} ''Note: evidently the timing adjustments for multiple maracas are still not guaranteed to succeed despite this initialization period. In such a scenario, additional software is required to manually make the adjustments.'' 8b28691782d881a632dfb329fe2503ad83d204ac File:Samba De Amigo Maracas.jpg 6 745 1726 2022-12-31T20:53:54Z Unknown user 0 wikitext text/x-wiki Samba De Amigo Maracas, including box, mat, and ultrasonic receiver. a968e0a97f8a767eb26bc635fe9b04c009d98270 File:Cha Cha Amigo Maracas.jpg 6 746 1728 2022-12-31T21:01:04Z Unknown user 0 wikitext text/x-wiki 3rd Party Maraca Controller 2d126d61178e41a5cabfcfc1ba36b7a30cea6943 Maple bus 0 113 1730 1681 2023-01-01T06:26:05Z Unknown user 0 /* Location Word */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> cd898232c64da1a9127ffdde1475c42b0a6837b5 File:VMU Development Resources.gz 6 747 1739 2023-01-01T07:00:57Z Unknown user 0 GyroVorbis moved page [[File:VMU Development Resources.gz]] to [[File:VMU Development Resources.zip]] wikitext text/x-wiki #REDIRECT [[File:VMU Development Resources.zip]] d48bcbe039721e7d7a3c544dedf43dd6e8ecd0f7 Jump pack peripheral 0 729 1740 1688 2023-01-01T07:21:08Z Unknown user 0 /* Vibration Mode (Byte 3) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 || 0 || 0 || 0 || continuous vibration mode (1: enable) |} a224d4fd747fa493f6dbf5f8fa712ddaeaaeb7db 1741 1740 2023-01-01T07:21:41Z Unknown user 0 /* Vibration Mode (Byte 3) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 26613948b03832ab2f69e61ad92215ba23dc9027 1742 1741 2023-01-01T07:23:15Z Unknown user 0 /* Inclination Direction and Power (Byte 2) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 7729c90b89decc38467a953280a6e01f1784b654 1743 1742 2023-01-01T07:23:38Z Unknown user 0 /* Vibration Mode (Byte 3) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 594166df242a5f42d00a65c6778a2afaeef1d4ea 1744 1743 2023-01-01T07:23:55Z Unknown user 0 /* Vibration Mode (Byte 3) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 4d8d5d607da935c9c96624016fe8af6356c1c3d1 1745 1744 2023-01-01T07:33:56Z Unknown user 0 wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Number of vibration sources (1 to 15) || Number of concurrent sources (1 to 15) || 0 || 0 |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} b85e2bfcfed6e838b91d9e3cd8fa1b68463b0e2e 1746 1745 2023-01-01T07:35:02Z Unknown user 0 /* Function Definition */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Number of vibration sources 1 to 15 (normally 1) || Number of concurrent sources 1 to 15 (normally 1) || 0 || 0 |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 43310dd598da6e94316a52961741b6caba8d30bc 1747 1746 2023-01-01T07:35:44Z Unknown user 0 /* Function Definition */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} a350e09512a3fb03ba5b821b0780d1b24820d411 1749 1747 2023-01-01T07:40:35Z Unknown user 0 wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. '''NOTE:''' Some information here is misleading and/or incomplete == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. Up to 15 words may be specified in order to set every vibration source as specified in the function definition. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 5b0536ab3888ecf28a036ebbca6015b6fbec7826 1750 1749 2023-01-01T07:40:48Z Unknown user 0 wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. Up to 15 words may be specified in order to set every vibration source as specified in the function definition. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence (continuous vibration mode must be disabled) There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 72ddccca90ebb6d22753d832286ef97e68e2a01e 1751 1750 2023-01-01T07:42:18Z Unknown user 0 /* Inclination Direction and Power (Byte 2) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. Up to 15 words may be specified in order to set every vibration source as specified in the function definition. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence ** Continuous vibration mode must be disabled ** Vibration source in the next word must still be set There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} b39d242fcbd52e542a4f463a550b5e50eddfd63d 1752 1751 2023-01-01T07:42:31Z Unknown user 0 /* Inclination Direction and Power (Byte 2) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. Up to 15 words may be specified in order to set every vibration source as specified in the function definition. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence ** Continuous vibration mode must be disabled ** Vibration source in the next byte must still be set There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} 964c69db3f4772357c492702cdc786d2b1a61ed9 1753 1752 2023-01-01T07:42:59Z Unknown user 0 /* Inclination Direction and Power (Byte 2) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. Up to 15 words may be specified in order to set every vibration source as specified in the function definition. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of X may be in the range [1,7] where 1 is low power and 7 is high power ** 0xX0: single stable vibration (i.e. no inclination) at power X ** 0xX8: positive inclination (ramp up) from power X up to max ** 0x8X: negative inclination (ramp down) from power X down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence ** Continuous vibration mode in mode byte must be disabled ** Vibration source in mode byte must still be set There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} b16e52b71ce8311c6f883f427351c1f2f8ed15ab 1754 1753 2023-01-01T07:55:55Z Unknown user 0 /* Inclination Direction and Power (Byte 2) */ wikitext text/x-wiki The jump pack acts as a sub-peripheral device on the [[Maple_bus|Maple Bus]]. == Vibration == The "set condition" command (0x0E) with vibration function code and 1 condition word is used to activate vibration. === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | 0 || 0 || Number of concurrent sources 1 to 15 (normally 1) || Number of vibration sources 1 to 15 (normally 1) |} === Condition Word === The following describes the layout of the condition word in the vibration "set condition" command. Up to 15 words may be specified in order to set every vibration source as specified in the function definition. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Vibration Cycles || Pulsation Frequency || Inclination Direction and Power || Vibration Mode |} ==== Vibration Cycles (Byte 0) ==== This value represents how many pulsation cycles to execute per inclination intensity. The number of cycles to execute is 1 more than the value specified. With inclination set, this value can be set to a maximum of 255. This value must be 0 when no inclination is set, so only a single cycle will execute in that case.* <nowiki>*</nowiki>The Performance TremorPak allows this value to be set to up to 255 when no inclination is set, but the OEM pack enforces this limitation. ==== Pulsation Frequency (Byte 1) ==== This value sets the frequency at which the motor pulsates. The pulsation is smooth - feels like a sine wave pulsation. At values near the maximum, the pulsation is not very noticeable at all. The valid range for this value is between 7 and 59. The extended device info from a vibration pack was very helpful in determining the appropriate frequency based on this value: Puru Puru Pack Produced By or Under License From SEGA ENTERPRISES,LTD. Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 Specifically, the text "Fm:4 - 30Hz". This correlates to "(value + 1) / 2" and matches what was observed in testing. ==== Inclination Direction and Power (Byte 2) ==== * For the following, the value of P may be in the range [1,7] where 1 is low power and 7 is high power ** 0xP0: single stable vibration (i.e. no inclination) at power P ** 0xP8: positive inclination (ramp up) from power P up to max ** 0x8P: negative inclination (ramp down) from power P down to min * A value of 0x00, 0x08, or 0x80 immediately stops the currently executing vibration sequence ** Continuous vibration mode in mode byte must be disabled ** Vibration source in mode byte must still be set There is a very noticeable change from one vibration power to the next when inclination is used and a long cycle period is selected. ==== Vibration Mode (Byte 3) ==== This byte must be set to the following. {| class="wikitable" |- ! Bit 7 <br> (MSb) !! Bit 6 !! Bit 5 !! Bit 4 !! Bit 3 !! Bit 2 !! Bit 1 !! Bit 0 <br> (LSb) |- | colspan="4" | vibration source 1 to 15 (usually 1)<br>0 is invalid || 0 || 0 || 0 || continuous vibration mode<br>(1: enable) |} ce6c6d23ad9a87753f897d4b679fe50b1b4ff4cb VMU peripheral 0 726 1748 1736 2023-01-01T07:36:44Z Unknown user 0 /* Function Definition */ wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions (x + 1) |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * A VMU cannot handle successive block write packets faster than about 10 ms per write ** After such error, the storage functionality acts as if it never received this sequence and never returns a response packet - it may be possible to successfully resend this sequence, but writing a "get last error" command would be necessary before starting over at the first sequence == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> b960740d59792bc9bc102c36e19115ab9753f5b4 Controller peripheral 0 727 1755 1690 2023-01-01T19:08:57Z Unknown user 0 wikitext text/x-wiki The controller acts as a main peripheral device on the [[Maple_bus|Maple Bus]]. == Controller == The "get condition" command (0x09) with controller function code is used to poll controller state. A "data transfer" command (0x08) is returned with controller function code word plus 2 words of data. The returned data must be parsed differently depending on the function definition for the controller. The below sections show how to parse data for a standard controller. === First Data Transfer Word === All button bits are 0 when pressed and 1 when released. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Left analog trigger 0 to 255<br>0: fully released<br>255: fully pressed || Right analog trigger 0 to 255<br>0: fully released<br>255: fully pressed || Button bits<br>0x01: Z<br>0x02: Y<br>0x04: X<br>0x08: D<br>0x10: Up-b<br>0x20: down-b<br>0x40: left-b<br>0x80: right-b || Button bits<br>0x01: C<br>0x02: B<br>0x04: A<br>0x08: Start<br>0x10: Up<br>0x20: Down<br>0x40: Left<br>0x80: Right |} === Second Data Transfer Word === {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Right analog stick up/down<br>0: fully up<br>128: center<br>255: fully down || Right analog stick left/right<br>0: fully left<br>128: center<br>255: fully right || Left analog up/down<br>0: fully up<br>128: center<br>255: fully down || Left analog left/right<br>0: fully left<br>128: center<br>255: fully right |} e9129014563ac07c5a06598b7ffd0de891df399f Memory card 0 748 1756 2023-01-01T19:10:53Z Unknown user 0 Created page with "Peripheral: Refer to [[VMU_peripheral#Storage|storage]] function in VMU peripheral" wikitext text/x-wiki Peripheral: Refer to [[VMU_peripheral#Storage|storage]] function in VMU peripheral e4cb1b9d9a2191eddf45d29827e362b7340ac00a File:Maple Bus SDCKB Occupancy.png 6 749 1757 2023-01-02T01:40:50Z Unknown user 0 wikitext text/x-wiki Maple Bus SDCKB Occupancy 550c2a2f5de07cd89e406bbe45cf2d8a78568f0a 1759 1757 2023-01-02T02:43:03Z Unknown user 0 Tails86 uploaded a new version of [[File:Maple Bus SDCKB Occupancy.png]] wikitext text/x-wiki Maple Bus SDCKB Occupancy 550c2a2f5de07cd89e406bbe45cf2d8a78568f0a Maple bus 0 113 1758 1730 2023-01-02T01:48:27Z Unknown user 0 Added SDCKB occupancy description wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 1b807aeb0cd45261fa0e2b71a0bf93561eb7267b 1761 1758 2023-01-02T03:46:08Z Unknown user 0 Added reset sequence wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 61a7b02aa4d519471150d2e59a67348d853cb517 File:Maple Bus Reset Sequence.png 6 750 1760 2023-01-02T03:44:25Z Unknown user 0 wikitext text/x-wiki Maple Bus Reset Sequence 18daca21aa712c24c8a91877a362a6e6789d082c File:LAN Adapter Box.jpg 6 751 1762 2023-01-02T07:07:27Z Unknown user 0 wikitext text/x-wiki Box for Dreamcast LAN Adapter d14a27460c9855933c9d2ed8c6f265b7bb3847c1 LAN adapter 0 31 1763 724 2023-01-02T07:14:51Z Unknown user 0 wikitext text/x-wiki [[File:LAN Adapter Box.jpg|thumb|LAN Adapter Box]] The Dreamcast '''LAN Adapter (HIT-300)''' is a Japanese-only peripheral that connects to the [[G2 bus]] in place of the modem and provides the Dreamcast with 10mbps network connectivity. It uses a Fujitsu MB86967 chip, and should not be confused with the more common and vastly superior [[Broadband adapter | Dreamcast Broadband Adapter]], which uses a RealTek 8139C chip. =Commercial Support= The only official software that works with the LAN adapter is the "Dream Passport 2 for LAN" web browser. No official games from any region are compatible with the LAN adapter. =Homebrew Support= Homebrew software that is compatible with the broadband adapter is usually also compatible with the LAN adapter; however, software is not often tested with the LAN adapter explicitly due to its rarity. It is also possible to use the LAN adapter for homebrew development as an alternative to the BBA, using [[dcload-ip]]. {{DCWiki:Stub}} 9719869d2f2b0568d5b7b62142c4bd43a853e53f File:Neo Geo Pocket Color Link Cable.jpg 6 752 1764 2023-01-02T07:18:15Z Unknown user 0 wikitext text/x-wiki Cable and Box for the Neo Geo Pocket Color to Dreamcast link cable. 47b5e1715ea43f30fcc93b2bc0aea1be9349bdca Neo Geo Pocket Color link cable 0 33 1765 273 2023-01-02T07:19:03Z Unknown user 0 wikitext text/x-wiki [[File:Neo Geo Pocket Color Link Cable.jpg|thumb|Box and Link Cable for the NGPC to DC]] The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported. * Bikkuriman 2000 Viva! Festival! connects to Bikkuriman 2000 Viva! Pocket Festival! * Capcom vs. SNK: Millennium Fight 2000 connects to SNK vs. Capcom: Match of the Millennium * Capcom vs. SNK 2: Millionaire Fighting 2001 connects to SNK vs. Capcom: Card Fighters 2 Expand Edition * Cool Cool Toon connects to Cool Cool Jam * The King of Fighters: Evolution connects to King of Fighters: Battle de Paradise * The King of Fighters Dream Match '99 connects to King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium {{DCWiki:Stub}} c67df74d2ae60164197738d250423fd68adf8a41 1766 1765 2023-01-02T07:27:31Z Unknown user 0 wikitext text/x-wiki [[File:Neo Geo Pocket Color Link Cable.jpg|thumb|Box and Link Cable for the NGPC to DC]] The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported and the cable is relatively rare. = Supported Titles= The following table is a list of Dreamcast games supporting the link cable along with their corresponding Neo Geo Pocket games. {| class="wikitable" |- ! Dreamcast Title !! Neo Geo Pocket Title |- | Bikkuriman 2000 Viva! Festival! || Bikkuriman 2000 Viva! Pocket Festival! |- | Capcom vs. SNK: Millennium Fight 2000 || SNK vs. Capcom: Match of the Millennium |- | Capcom vs. SNK 2: Millionaire Fighting 2001 || Capcom: Card Fighters 2 Expand Edition |- | Cool Cool Toon connects || Cool Cool Jam |- | The King of Fighters: Evolution || King of Fighters: Battle de Paradise |- | The King of Fighters Dream Match '99 || King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium |- |} {{DCWiki:Stub}} c2a5d446577a97993c3901e900b34ccf98892d34 1767 1766 2023-01-02T07:34:18Z Unknown user 0 wikitext text/x-wiki [[File:Neo Geo Pocket Color Link Cable.jpg|thumb|Box and Link Cable for the NGPC to DC]] The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported and the cable is relatively rare. = Supported Titles= The following table is a list of Dreamcast games supporting the link cable along with their corresponding Neo Geo Pocket games. {| class="wikitable" |- ! Dreamcast Title !! Neo Geo Pocket Title |- | Bikkuriman 2000 Viva! Festival! || Bikkuriman 2000 Viva! Pocket Festival! |- | Capcom vs. SNK: Millennium Fight 2000 || SNK vs. Capcom: Match of the Millennium |- | Capcom vs. SNK 2: Millionaire Fighting 2001 || Capcom: Card Fighters 2 Expand Edition |- | Cool Cool Toon connects || Cool Cool Jam |- | The King of Fighters: Evolution || King of Fighters: Battle de Paradise |- | The King of Fighters Dream Match '99 || King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium |- |} = Homebrew Support= To date, no known indie developer have made an attempt to utilize the cable for a DC and NGPC linkable homebrew game. No indie development libraries or resources are known to exist with this support either. {{DCWiki:Stub}} c1085079814fb97e772f066e0979de73943d5789 1768 1767 2023-01-02T07:34:56Z Unknown user 0 wikitext text/x-wiki [[File:Neo Geo Pocket Color Link Cable.jpg|thumb|Box and Link Cable for the NGPC to DC]] The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported and the cable is relatively rare. = Commercial Software= The following table is a list of Dreamcast games supporting the link cable along with their corresponding Neo Geo Pocket games. {| class="wikitable" |- ! Dreamcast Title !! Neo Geo Pocket Title |- | Bikkuriman 2000 Viva! Festival! || Bikkuriman 2000 Viva! Pocket Festival! |- | Capcom vs. SNK: Millennium Fight 2000 || SNK vs. Capcom: Match of the Millennium |- | Capcom vs. SNK 2: Millionaire Fighting 2001 || Capcom: Card Fighters 2 Expand Edition |- | Cool Cool Toon connects || Cool Cool Jam |- | The King of Fighters: Evolution || King of Fighters: Battle de Paradise |- | The King of Fighters Dream Match '99 || King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium |- |} = Homebrew Software= To date, no known indie developer have made an attempt to utilize the cable for a DC and NGPC linkable homebrew game. No indie development libraries or resources are known to exist with this support either. {{DCWiki:Stub}} 4f954cb223f6451e4003c7871268eac1816a4a45 1769 1768 2023-01-02T07:36:20Z Unknown user 0 wikitext text/x-wiki [[File:Neo Geo Pocket Color Link Cable.jpg|thumb|Box and Link Cable for the NGPC to DC]] The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported and the cable is relatively rare. = Commercial Software= The following table is a list of Dreamcast games supporting the link cable along with their corresponding Neo Geo Pocket games. {| class="wikitable" |- ! Dreamcast Title !! Neo Geo Pocket Title |- | Bikkuriman 2000 Viva! Festival! || Bikkuriman 2000 Viva! Pocket Festival! |- | Capcom vs. SNK: Millennium Fight 2000 || SNK vs. Capcom: Match of the Millennium |- | Capcom vs. SNK 2: Millionaire Fighting 2001 || Capcom: Card Fighters 2 Expand Edition |- | Cool Cool Toon connects || Cool Cool Jam |- | The King of Fighters: Evolution || King of Fighters: Battle de Paradise |- | The King of Fighters Dream Match '99 || King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium |- |} = Homebrew Software= * To date, no known indie developers have made an attempt to utilize the cable for a DC and NGPC linkable homebrew game. * No indie development libraries or resources are known to exist with this support either. * No Emulators of either platform are known to support communication with an emulator of the other via emulating this link cable {{DCWiki:Stub}} 3d1ff3c6e867382ab7197b8f01b49a53cd088bce 1770 1769 2023-01-02T07:36:40Z Unknown user 0 wikitext text/x-wiki [[File:Neo Geo Pocket Color Link Cable.jpg|thumb|Box and Link Cable for the NGPC to DC]] The Neo Geo Pocket Color link cable is a cable that connects the Sega Dreamcast to the SNK Neo Geo Pocket Color handheld system via serial communication. Due to the limited lifespan of the Neo Geo Pocket Color, only a few titles were supported and the cable is relatively rare. = Commercial Software= The following table is a list of Dreamcast games supporting the link cable along with their corresponding Neo Geo Pocket games. {| class="wikitable" |- ! Dreamcast Title !! Neo Geo Pocket Title |- | Bikkuriman 2000 Viva! Festival! || Bikkuriman 2000 Viva! Pocket Festival! |- | Capcom vs. SNK: Millennium Fight 2000 || SNK vs. Capcom: Match of the Millennium |- | Capcom vs. SNK 2: Millionaire Fighting 2001 || Capcom: Card Fighters 2 Expand Edition |- | Cool Cool Toon connects || Cool Cool Jam |- | The King of Fighters: Evolution || King of Fighters: Battle de Paradise |- | The King of Fighters Dream Match '99 || King of Fighters R-2 and SNK vs. Capcom: Match of the Millennium |- |} = Homebrew Software= * To date, no known indie developers have made an attempt to utilize the cable for a DC and NGPC linkable homebrew game. * No indie development libraries or resources are known to exist with this support for either * No Emulators of either platform are known to support communication with an emulator of the other via emulating this link cable {{DCWiki:Stub}} 0923b7743ae0e9f222df1b7800f59a5fa73e99fd Engine & Library 0 27 1771 987 2023-01-02T08:15:14Z Unknown user 0 wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[https://simulant-engine.appspot.com Simulant] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] 6173b79038dc6ab616a5a1f8a0678a1b6364307a File:Versus Cable.jpg 6 753 1772 2023-01-02T08:36:56Z Unknown user 0 wikitext text/x-wiki Dreamcast Versus Cable with Box d27a4a4853ced00aae29c43015f5b2fb3d958e23 VS cable 0 32 1773 274 2023-01-02T08:45:12Z Unknown user 0 wikitext text/x-wiki [[File:Versus Cable.jpg|thumb|Dreamcast Versus Cable with Box]] The Dreamcast VS cable is a rare, serial-based cable that connects two Dreamcast consoles together for multiplayer games. The cable was only released in Japan. There was also an aftermarket version released by Dragoncast, but this cable is also rare. Only 5 titles are compatible. =Commercial Support= The following games were compatible with the cable: * Aero Dancing F * Aero Dancing i * Cyber Troopers Virtual-On: Oratorio Tangram * F355 Challenge * Sega Tetris =Homebrew Support= * To date no homebrew or indie titles are known to have supported the versus cable * The homebrew development libraries have no support for it * No known Dreamcast emulators emulate DC-to-DC connectivity via the cable {{DCWiki:Stub}} 6ce5303a0596fb6c9e524b583435136dfad54c92 Texconv 0 155 1774 955 2023-01-02T09:02:36Z Unknown user 0 wikitext text/x-wiki == Description == Texconv is a old but trusty tool by Anton Norgren (Tvspelsfreak on DCEmulation.org forums) to convert .png files into .dtex (some say .dtx) format. '''Source : ''' https://github.com/tvspelsfreak/texconv == Installation == Tested on Linux Mint (2020-01-16) <syntaxhighlight lang="bash"> sudo apt install qt5-default qtbase5-dev git clone https://github.com/tvspelsfreak/texconv cd texconv qmake make </syntaxhighlight> f192f2df49228368695f4af93151680e0ca5c641 32MB RAM expansion 0 284 1775 1715 2023-01-02T22:16:34Z Unknown user 0 /* KallistiOS */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== A [https://github.com/darcagn/KallistiOS/tree/32mb-mk4 fork of KallistiOS] exists which supports 32MB expansion, with an aim to be merged into the main repository soon. To build it, build both the toolchain and KallistiOS [[Getting Started with Dreamcast development|using the instructions here]], but clone the git repository using this command instead: git clone -b 32mb-mk4 https://github.com/darcagn/KallistiOS.git kos If you already have an existing toolchain built, you must rebuild it to support 32MB expansion. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 67152bea205113e79441eb8cc9240bd4dbd60ad1 1776 1775 2023-01-03T00:32:13Z Unknown user 0 /* KallistiOS */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== A [https://gitlab.com/cepawiel/lxdream-nitro/-/tree/big_ram fork of lxdream-nitro] by [[cepawiel]] exists which can be built to support 32MB expansion. git clone -b big_ram https://gitlab.com/cepawiel/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 2147e5dcc5d8aef9b0375f2322cea5206d65b332 1777 1776 2023-01-03T01:26:48Z Unknown user 0 /* lxdream Dreamcast Emulator */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when built with the <code>-DMOD_32MB_RAM=true</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell. [[:File:Memtest.tar.gz]] ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 87aefe24266fb89ac22e3e4efa7f1ef68d2c58af 1778 1777 2023-01-03T02:08:36Z Unknown user 0 /* memtest */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when built with the <code>-DMOD_32MB_RAM=true</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir -DMOD_32MB_RAM=true meson compile -C builddir ./builddir/lxdream-nitro -h ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell and adapted for [https://github.com/KallistiOS/KallistiOS/tree/master/examples/dreamcast/basic/memtest32 inclusion in KalllistiOS as an example]. ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X fdcef4d723b09d42b72ee732fe95b9a0d99b3c40 1780 1778 2023-01-03T22:50:59Z Unknown user 0 /* lxdream Dreamcast Emulator */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when run with the <code>--ram-size=32</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir meson compile -C builddir ./builddir/lxdream-nitro --ram-size=32 ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===memtest=== A memory testing utility supporting 16MB and 32MB Dreamcasts has been written by tsowell and adapted for [https://github.com/KallistiOS/KallistiOS/tree/master/examples/dreamcast/basic/memtest32 inclusion in KalllistiOS as an example]. ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X 46609d7624f2f622634ca357ea225e0603239fbc Getting Started with Dreamcast development 0 694 1779 1538 2023-01-03T17:21:15Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make Toolchain is now built. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 0533ba14036d000bf1b2e6cb7cda4d793d3b6b52 File:Zip Drive.jpg 6 754 1781 2023-01-04T00:00:08Z Unknown user 0 wikitext text/x-wiki Zip Drive Peripheral for the Sega Dreamcast b4aec66a06dc9c5b1fae3fb9dfc3dcbb3452a5db Zip drive 0 29 1782 270 2023-01-04T00:02:13Z Unknown user 0 wikitext text/x-wiki [[File:Zip Drive.jpg|thumb|Zip Drive Peripheral attached to a Dreamcast]] The Dreamcast Zip drive was a planned, unreleased upgrade for the Dreamcast console. It would have connected to the bottom of the Dreamcast using the [[G2 bus]] connector, similar to the [[Dreamcast Karaoke]] unit. It would have added a Zip disk drive as well as a USB port to the Dreamcast. = Prototypes = Despite the fact that the peripheral was never technically released, there are a very limited number fully complete prototypes in circulation. {{DCWiki:Stub}} 5040906b29af2789018e9145e99a4bf70b41a7f8 Case whitening 0 743 1783 1723 2023-01-04T18:45:28Z Unknown user 0 wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray. == Products == === DIY === DIY solutions consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The brightening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags so that the yellowed surfaces are all visible from one side of the bag # Leave the bag(s) in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 82b85c6eba5d541afe1366ceee3034debb9aad85 1784 1783 2023-01-04T18:48:01Z Unknown user 0 /* Process */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray. == Products == === DIY === DIY solutions consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The brightening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s) in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 0925fc8a05034da7892e53ea958a79b78c5db6a4 1785 1784 2023-01-04T18:48:27Z Unknown user 0 /* Process */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray. == Products == === DIY === DIY solutions consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The brightening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 77f71f833548082563fef94bda8c5199909daaa3 1786 1785 2023-01-04T18:50:17Z Unknown user 0 /* Why Dreamcast Plastic Yellows */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === DIY === DIY solutions consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The brightening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 9e111b4977b651ad7d08b352d3dcb2629c9315a0 1787 1786 2023-01-04T18:51:51Z Unknown user 0 /* Process */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === DIY === DIY solutions consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The brightening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast and reattach logo sticker and labels <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> efecf814b004a651381cc37e44e76fbdf3375e02 User:Tails86 2 755 1788 2023-01-04T19:02:43Z Unknown user 0 Created page with "Dreamcast/Sega peripheral enthusiast == Organizations == https://github.com/orgs/OrangeFox86/repositories" wikitext text/x-wiki Dreamcast/Sega peripheral enthusiast == Organizations == https://github.com/orgs/OrangeFox86/repositories c0523b07165ecd73ee0eb6e79b90b951386f61a5 Case whitening 0 743 1789 1787 2023-01-04T19:25:59Z Unknown user 0 /* Process */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === DIY === DIY solutions consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The whitening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast and reattach logo sticker and labels <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> b78a71d929417251bdd26de0affdb9e4f96ae59a 1790 1789 2023-01-04T19:29:49Z Unknown user 0 /* DIY */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === Retr0bright === The DIY Retr0bright solution consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The whitening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast and reattach logo sticker and labels <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 387189c4e71f5f18c463b7fdbf71007013f90aab 1791 1790 2023-01-04T19:32:54Z Unknown user 0 wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright Wiki''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === Retr0bright === The DIY Retr0bright solution consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/><ref>''[https://www.retr0bright.com/make.html] retr0bright''</ref> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The whitening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast and reattach logo sticker and labels <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 1b0f722a29fc165be88fc1b506a777e465215f70 1792 1791 2023-01-04T19:33:15Z Unknown user 0 /* Products */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright Wiki''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === Retr0bright === The DIY Retr0bright solution consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/><ref>''[https://www.retr0bright.com/make.html] Retr0bright make''</ref> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The whitening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the brightening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast and reattach logo sticker and labels <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 8a4a55395b08597116e01f73483b939153654c4b 1793 1792 2023-01-04T19:34:31Z Unknown user 0 /* Process */ wikitext text/x-wiki The plastic case of the Dreamcast is prone to yellowing, but there are products available to help whiten it. == Why Dreamcast Plastic Yellows == Dreamcast cases are made from ABS, and ABS is known for turning yellow when exposed to UV of sunlight and/or excessive heat.<ref name="retrobright">''[https://en.wikipedia.org/wiki/Retr0bright] Retr0bright Wiki''</ref> The yellow color becomes more apparent because the standard base color of the plastic is a light gray which contrasts against the yellow. == Products == === Retr0bright === The DIY Retr0bright solution consist of hydrogen peroxide and a TAED-based laundry booster.<ref name="retrobright"/><ref>''[https://www.retr0bright.com/make.html] Retr0bright make''</ref> === Retro-Brite === [https://retro-brite.com/ Retro-Brite] is a spray-on gel which may be purchased from Amazon. == Process == Do the following to whiten a Dreamcast case: # Disassemble the plastic case into the bottom shell, top shell, CD lid, controller port cover, and buttons; set aside all electronics # Carefully remove the Dreamcast logo sticker from the lid and labels on the bottom, if desired ## The whitening process WILL discolor stickers if they aren't removed # Put on gloves and spray down every exposed surface of all of the plastic pieces with the whitening solution # Put each plastic piece into one or more plastic bags or some other clear, enclosed container so that the yellowed surfaces are all facing upwards # Leave the bag(s)/container in full sun on warm days or under a UV light in a warm area for 8 to 24 hours of exposure, checking on their progress every few hours # Remove all pieces from bag(s), rinse with tap water, and let dry # The process may be repeated if more whitening is desired # Once satisfied, reassemble your Dreamcast and reattach logo sticker and labels <br> [[File:Yellowed Dreamcast.jpg|frameless|Yellowed Dreamcast]] -> [[File:Whitened Dreamcast.jpg|frameless|Whitened Dreamcast]] <br> == References == <references /> 40b5e0369da4884c23169db910e581e12ddb28d6 NetBSD/Dreamcast 0 756 1794 2023-01-05T00:37:40Z Unknown user 0 Created page with "'''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html relea..." wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. Example is using 10.0_BETA References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Example== ===Initial folder setup=== Create a working directory in your home folder and enter it: mkdir ~/netbsd cd netbsd Create additional directories for files: mkdir -p usr obj src-tars xsrc-tars ===Download files=== Download from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== for file in src-tars/*.tar.gz; do tar -zxf $file -C usr; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file -C usr; done ===Build toolchain=== cd usr/src /build.sh -U -O ~/netbsd/obj -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -j is number of threads during build, -m is machine type, tools is toolchain) run the following command and take note of your tooldir name, e.g. on Linux: ls -l ~/netbsd/obj will returns something like... - tooldir.Linux-6.0.15-gentoo-x86_64 - tools The one with "tooldir" in the name is the directory to note. ===Build kernel=== cd sys/arch/dreamcast/conf If your target Dreamcast is modded with 32MB of RAM and you wish to build for that, open std.dreamcast and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types, or copy one of them to a new file in the same dir and edit to configure your own kernel options. Run nbconfig on your kernel config, putting in the tooldir you noted before: ~/netbsd/obj/<YOUR_TOOLDIR_NAME>/bin/nbconfig GENERIC Then build dependencies and kernel: ~/netbsd/obj/<YOUR_TOOLDIR_NAME>/bin/nbmake-dreamcast depend ~/netbsd/obj/<YOUR_TOOLDIR_NAME>/bin/nbmake-dreamcast ===Build userland=== cd ~/netbsd/usr/src ./build.sh -U -u -j2 -O ~/netbsd/obj -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== ./build.sh -U -u -O ../../obj -j30 -x -X ../xsrc -m dreamcast release (-x is to build the X server, -X is the path of the X source code) 073c15a751c273a5dd2e073d750fc527651b3ec0 1797 1794 2023-01-05T01:02:33Z Unknown user 0 wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Example== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd netbsd Create additional directories for files: mkdir -p obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd sys/arch/dreamcast/conf If your target Dreamcast is modded with 32MB of RAM and you wish to build for that, open std.dreamcast and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types, or copy one of them to a new file in the same dir and edit to configure your own kernel options. Run nbconfig on your kernel config, putting in the tooldir you noted before: ~/netbsd/obj/<YOUR_TOOLDIR_NAME>/bin/nbconfig GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast ===Build userland=== cd ~/netbsd/src ./build.sh -U -u -j2 -O ~/netbsd/obj -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -u -O ../../obj -j30 -x -X ../xsrc -m dreamcast release (-x is to build the X server, -X is the path of the X source code) 470bc53e0f4fb8f90f356032c990097d25e728d7 1801 1797 2023-01-05T01:31:44Z Unknown user 0 wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Example== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) 210f5154a7dab092c5f14b7a2d0b997a7a1b9e99 1804 1801 2023-01-05T01:44:18Z Unknown user 0 /* Example */ wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Building NetBSD source from scratch== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) ===Output directories=== * <code>~/netbsd/dest</code> will contain a copy of your NetBSD/Dreamcast userland. * <code>~/netbsd/release/dreamcast/binary</code> will contain packaged copies of kernels and userland sets for resharing with others. 3b3fb42628eec7f951edea2de199d4174ad5c9f5 1806 1804 2023-01-05T04:02:47Z Unknown user 0 wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Building NetBSD source from scratch== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) ===Output directories=== * <code>~/netbsd/dest</code> will contain a copy of your NetBSD/Dreamcast userland. * <code>~/netbsd/release/dreamcast/binary</code> will contain packaged copies of kernels and userland sets for resharing with others. ==Kernel Options== ===NFS booting=== options NFS_BOOT_BOOTSTATIC options NFS_BOOTSTATIC_MYIP="\"192.168.0.100\"" options NFS_BOOTSTATIC_GWIP="\"192.168.0.1\"" options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" options NFS_BOOTSTATIC_SERVADDR="\"192.168.0.2\"" options NFS_BOOTSTATIC_SERVER="\"192.168.0.2:/home/user/netbsdmount\"" options NFS_BOOT_RWSIZE=1024 b45969ff7e79b1e6509d8960be1fbfeed2b2cc17 1807 1806 2023-01-05T04:03:42Z Unknown user 0 wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Building NetBSD source from scratch== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) ===Output directories=== * <code>~/netbsd/dest</code> will contain a copy of your NetBSD/Dreamcast userland. * <code>~/netbsd/release/dreamcast/binary</code> will contain packaged copies of kernels and userland sets for resharing with others. ==Kernel Options== ===NFS booting=== options NFS_BOOT_BOOTSTATIC options NFS_BOOTSTATIC_MYIP="\"192.168.0.100\"" options NFS_BOOTSTATIC_GWIP="\"192.168.0.1\"" options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" options NFS_BOOTSTATIC_SERVADDR="\"192.168.0.2\"" options NFS_BOOTSTATIC_SERVER="\"192.168.0.2:/home/user/netbsdmount\"" options NFS_BOOT_RWSIZE=1024 ==AICA== Still needed? Not sure http://mail-index.netbsd.org/port-dreamcast/2017/07/25/msg000306.html ffadda60feed3c7b7fa17d0bb91bd3b66084af56 1808 1807 2023-01-05T04:04:19Z Unknown user 0 wikitext text/x-wiki '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Building NetBSD source from scratch== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) ===Output directories=== * <code>~/netbsd/dest</code> will contain a copy of your NetBSD/Dreamcast userland. * <code>~/netbsd/release/dreamcast/binary</code> will contain packaged copies of kernels and userland sets for resharing with others. ==Kernel Options== ===NFS booting=== options NFS_BOOT_BOOTSTATIC options NFS_BOOTSTATIC_MYIP="\"192.168.0.100\"" options NFS_BOOTSTATIC_GWIP="\"192.168.0.1\"" options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" options NFS_BOOTSTATIC_SERVADDR="\"192.168.0.2\"" options NFS_BOOTSTATIC_SERVER="\"192.168.0.2:/home/user/netbsdmount\"" options NFS_BOOT_RWSIZE=1024 b45969ff7e79b1e6509d8960be1fbfeed2b2cc17 DCWiki:Software 4 81 1795 1708 2023-01-05T00:38:13Z Unknown user 0 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * [[Online Services]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] * [[VMU development]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[Useful programming tips]] * [[NetBSD/Dreamcast]] |} |} 37f2e5e93182c994281624482d0d505722bb4b46 File:Sega Extreme Sports.gif 6 757 1796 2023-01-05T01:00:20Z Unknown user 0 wikitext text/x-wiki Animation of the dynamic lighting/bloom lens flare effect from the game 80906d41099cd00e5dce0504977956c5a3f8c445 Games that pushed the console 0 758 1798 2023-01-05T01:08:32Z Unknown user 0 Created page with "This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced s..." wikitext text/x-wiki This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced special effects, flexing special features of the hardware, or doing some combination of the above with impressive frame-rates, this page is here to both honor their achievements, analyze how they did it, and shed light on some of the highest-end of what the Dreamcast's hardware is capable of. = Dead or Alive 2 = = HeadHunter 2 = = Sega Extreme Sports = [[File:Sega Extreme Sports.gif|thumb|Bloom and Lens Flare Effect]] = Shenmue 1 + 2 = = Soul Calibur = = Super Magnetic Neo = = Wacky Races = 5250de842aeee4bf8e75e07a3bba600e74ff2023 1799 1798 2023-01-05T01:08:54Z Unknown user 0 wikitext text/x-wiki This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced special effects, flexing special features of the hardware, or doing some combination of the above with impressive frame-rates, this page is here to both honor their achievements, analyze how they did it, and shed light on some of the highest-end of what the Dreamcast's hardware is capable of. = Dead or Alive 2 = = Head Hunter 2 = = Sega Extreme Sports = [[File:Sega Extreme Sports.gif|thumb|Bloom and Lens Flare Effect]] = Shenmue 1 + 2 = = Soul Calibur = = Super Magnetic Neo = = Wacky Races = b3cc57fbace46808b8975d7e4030e58c32f0320e 1800 1799 2023-01-05T01:09:29Z Unknown user 0 wikitext text/x-wiki This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced special effects, flexing special features of the hardware, or doing some combination of the above with impressive frame-rates, this page is here to honor their achievements, analyze how they did it, and shed light on some of the highest-end of what the Dreamcast's hardware is capable of. = Dead or Alive 2 = = Head Hunter 2 = = Sega Extreme Sports = [[File:Sega Extreme Sports.gif|thumb|Bloom and Lens Flare Effect]] = Shenmue 1 + 2 = = Soul Calibur = = Super Magnetic Neo = = Wacky Races = f3c206fb9e3c1ec24cc0241f3d002d38a7784443 1802 1800 2023-01-05T01:33:09Z Unknown user 0 wikitext text/x-wiki This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced special effects, flexing special features of the hardware, or doing some combination of the above with impressive frame-rates, this page is here to honor their achievements, analyze how they did it, and shed light on some of the highest-end of what the Dreamcast's hardware is capable of. = Dead or Alive 2 = = Head Hunter 2 = = Sega Extreme Sports = [[File:Sega Extreme Sports.gif|thumb|Lens Flare Effect]] = Shenmue 1 + 2 = = Soul Calibur = = Super Magnetic Neo = = Wacky Races = dcbc6d5292424eb5b7618add2da8f86046c62251 1805 1802 2023-01-05T01:48:43Z Unknown user 0 wikitext text/x-wiki This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced special effects, flexing special features of the hardware, or doing some combination of the above with impressive frame-rates, this page is here to honor their achievements, analyze how they did it, and shed light on some of the highest-end of what the Dreamcast's hardware is capable of. = Dead or Alive 2 = = Death Crimson 2 = = Head Hunter 2 = = Rez = = Sega Extreme Sports = [[File:Sega Extreme Sports.gif|thumb|Lens Flare Effect]] = Shenmue 1 + 2 = = Skies of Arcadia = = Soul Calibur = = Super Magnetic Neo = = Wacky Races = dfca4ed5697cb1089454e5c91f7d2e4004fa3361 1809 1805 2023-01-05T07:03:16Z Unknown user 0 wikitext text/x-wiki This page serves as a showcase and hall of fame for those games which took the DC to its limits. Whether this was by featuring a high polygon count, massive worlds, advanced special effects, flexing special features of the hardware, or doing some combination of the above with impressive frame-rates, this page is here to honor their achievements, analyze how they did it, and shed light on some of the highest-end of what the Dreamcast's hardware is capable of. = Dead or Alive 2 = = Death Crimson 2 = = Head Hunter = = Rez = = Sega Extreme Sports = [[File:Sega Extreme Sports.gif|thumb|Lens Flare Effect]] = Shenmue 1 + 2 = = Skies of Arcadia = = Soul Calibur = = Super Magnetic Neo = = Wacky Races = 2025af6ffa38e510dbc89e78fd759627e15693da VMU peripheral 0 726 1803 1748 2023-01-05T01:37:47Z Unknown user 0 wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions (x + 1) |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * A VMU cannot handle successive block write packets faster than about 10 ms per write ** After such error, the storage functionality acts as if it never received this sequence and never returns a response packet - it may be possible to successfully resend this sequence, but writing a "get last error" command would be necessary before starting over at the first sequence ** The Dreamcast does each read/write sequence on the same cadence as controller polling (about every 16 ms) == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> 268dfb38f3f936a62b469e1babbe14dc6bed53d8 GDI format 0 759 1810 2023-01-05T20:53:10Z Unknown user 0 Created page with "Sega Dreamcast GD-ROM images are most commonly using the GDI file format. Example GDI taken from Crazy Taxi: 3 1 0 4 2352 track01.bin 0 2 600 0 2352 track02.raw 0 3 45000..." wikitext text/x-wiki Sega Dreamcast GD-ROM images are most commonly using the GDI file format. Example GDI taken from Crazy Taxi: 3 1 0 4 2352 track01.bin 0 2 600 0 2352 track02.raw 0 3 45000 4 2352 track03.bin 0 The first line is the total number of tracks in the image. Each subsequent line describes each track of the disc. All GD-ROMs are at least 3 tracks. The format of each line is as follows: [Track Number] [Beginning LBA] [Track Type] [Sector Size] [Filename] [Offset] The track type is always <code>4</code> for data tracks, and <code>0</code> for audio tracks. Sector size is <code>2352</code> for raw data tracks containing error correction, as well as audio tracks. <code>2048</code> is used for tracks with error correction stripped. The offset field should always be <code>0</code>. Tracks 1 and 2 are the standard density CD-ROM tracks accessible by standard drives. The first track may contain goodies for the owner, like wallpapers or screensavers. The second is an audio track usually warning the user not to play the disc in an audio CD player. The high density region starts with track 3. Track 3 always starts at an LBA of 45000. On games with no audio tracks, there will only be 3 tracks total. On games with audio tracks, track 3 will be the ISO9660 header, followed by all of the data tracks, and finally the last track will contain the actual file data pointed to by the ISO9660 filesystem within track 3. Example GDI taken from Quake III Arena: 20 1 0 4 2352 track01.bin 0 2 756 0 2352 track02.raw 0 3 45000 4 2352 track03.bin 0 4 240811 0 2352 track04.raw 0 5 253507 0 2352 track05.raw 0 6 265334 0 2352 track06.raw 0 7 281311 0 2352 track07.raw 0 8 296397 0 2352 track08.raw 0 9 310270 0 2352 track09.raw 0 10 324436 0 2352 track10.raw 0 11 339323 0 2352 track11.raw 0 12 355185 0 2352 track12.raw 0 13 368487 0 2352 track13.raw 0 14 382523 0 2352 track14.raw 0 15 392248 0 2352 track15.raw 0 16 402684 0 2352 track16.raw 0 17 412416 0 2352 track17.raw 0 18 423159 0 2352 track18.raw 0 19 430167 0 2352 track19.raw 0 20 437360 4 2352 track20.bin 0 In this case, the disc contains 20 tracks. Track 1 is the CD-ROM data track, track 2 is the audio warning track, track 3 is a high density ISO9660 filesystem, tracks 4 through 19 are audio tracks used within the game, and track 20 contains actual file data described by the filesystem in track 3. The last track is always a data track, and the game's binary is always the last file on the disc. f7e41d00351ecfe8b83cbbac127a94fe5527add2 1811 1810 2023-01-05T20:53:19Z Unknown user 0 wikitext text/x-wiki Sega Dreamcast GD-ROM images are most commonly using the GDI file format. Example GDI taken from Crazy Taxi: 3 1 0 4 2352 track01.bin 0 2 600 0 2352 track02.raw 0 3 45000 4 2352 track03.bin 0 The first line is the total number of tracks in the image. Each subsequent line describes each track of the disc. All GD-ROMs are at least 3 tracks. The format of each line is as follows: [Track Number] [Beginning LBA] [Track Type] [Sector Size] [Filename] [Offset] The track type is always <code>4</code> for data tracks, and <code>0</code> for audio tracks. Sector size is <code>2352</code> for raw data tracks containing error correction, as well as audio tracks. <code>2048</code> is used for tracks with error correction stripped. The offset field should always be <code>0</code>. Tracks 1 and 2 are the standard density CD-ROM tracks accessible by standard drives. The first track may contain goodies for the owner, like wallpapers or screensavers. The second is an audio track usually warning the user not to play the disc in an audio CD player. The high density region starts with track 3. Track 3 always starts at an LBA of 45000. On games with no audio tracks, there will only be 3 tracks total. On games with audio tracks, track 3 will be the ISO9660 header, followed by all of the data tracks, and finally the last track will contain the actual file data pointed to by the ISO9660 filesystem within track 3. Example GDI taken from Quake III Arena: 20 1 0 4 2352 track01.bin 0 2 756 0 2352 track02.raw 0 3 45000 4 2352 track03.bin 0 4 240811 0 2352 track04.raw 0 5 253507 0 2352 track05.raw 0 6 265334 0 2352 track06.raw 0 7 281311 0 2352 track07.raw 0 8 296397 0 2352 track08.raw 0 9 310270 0 2352 track09.raw 0 10 324436 0 2352 track10.raw 0 11 339323 0 2352 track11.raw 0 12 355185 0 2352 track12.raw 0 13 368487 0 2352 track13.raw 0 14 382523 0 2352 track14.raw 0 15 392248 0 2352 track15.raw 0 16 402684 0 2352 track16.raw 0 17 412416 0 2352 track17.raw 0 18 423159 0 2352 track18.raw 0 19 430167 0 2352 track19.raw 0 20 437360 4 2352 track20.bin 0 In this case, the disc contains 20 tracks. Track 1 is the CD-ROM data track, track 2 is the audio warning track, track 3 is a high density ISO9660 filesystem, tracks 4 through 19 are audio tracks used within the game, and track 20 contains actual file data described by the filesystem in track 3. The last track is always a data track, and the game's binary is always the last file on the disc. eb39281d59905d84792c9e8f9b3cc66abcf42e63 1812 1811 2023-01-05T20:54:33Z Unknown user 0 wikitext text/x-wiki Sega Dreamcast GD-ROM images are most commonly using the GDI file format. Example GDI taken from Crazy Taxi: 3 1 0 4 2352 track01.bin 0 2 600 0 2352 track02.raw 0 3 45000 4 2352 track03.bin 0 The first line is the total number of tracks in the image. Each subsequent line describes each track of the disc. All GD-ROMs are at least 3 tracks. The format of each line is as follows: [Track Number] [Beginning LBA] [Track Type] [Sector Size] [Filename] [Offset] The track type is always <code>4</code> for data tracks, and <code>0</code> for audio tracks. Sector size is <code>2352</code> for raw data tracks containing error correction, as well as audio tracks. <code>2048</code> is used for tracks with error correction stripped. The offset field should always be <code>0</code>. Tracks 1 and 2 are the standard density CD-ROM tracks accessible by standard drives. The first track may contain goodies for the owner, like wallpapers or screensavers. The second is an audio track usually warning the user not to play the disc in an audio CD player. The high density region starts with track 3. Track 3 always starts at an LBA of 45000. On games with no audio tracks, there will only be 3 tracks total. On games with audio tracks, track 3 will be the ISO9660 header, followed by all of the audio tracks, and finally the last track will contain the actual file data pointed to by the ISO9660 filesystem within track 3. Example GDI taken from Quake III Arena: 20 1 0 4 2352 track01.bin 0 2 756 0 2352 track02.raw 0 3 45000 4 2352 track03.bin 0 4 240811 0 2352 track04.raw 0 5 253507 0 2352 track05.raw 0 6 265334 0 2352 track06.raw 0 7 281311 0 2352 track07.raw 0 8 296397 0 2352 track08.raw 0 9 310270 0 2352 track09.raw 0 10 324436 0 2352 track10.raw 0 11 339323 0 2352 track11.raw 0 12 355185 0 2352 track12.raw 0 13 368487 0 2352 track13.raw 0 14 382523 0 2352 track14.raw 0 15 392248 0 2352 track15.raw 0 16 402684 0 2352 track16.raw 0 17 412416 0 2352 track17.raw 0 18 423159 0 2352 track18.raw 0 19 430167 0 2352 track19.raw 0 20 437360 4 2352 track20.bin 0 In this case, the disc contains 20 tracks. Track 1 is the CD-ROM data track, track 2 is the audio warning track, track 3 is a high density ISO9660 filesystem, tracks 4 through 19 are audio tracks used within the game, and track 20 contains actual file data described by the filesystem in track 3. The last track is always a data track, and the game's binary is always the last file on the disc. e20ca72e369ba59ef4996a6b44051927ffb99860 Dumping GD-ROMs 0 6 1813 556 2023-01-05T21:09:40Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]], [[Broadband adapter]], or [[LAN adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). Do not use Dreamshell for dumping GD-ROMs as the ripper software in Dreamshell is unreliable. GD-ROM images are most commonly stored in the [[GDI format]]. {| class="wikitable" |+Methods for dumping and types of discs possible to dump |- ! ! Dreamcast<br /> with Broadband/LAN adapter ! Dreamcast<br /> with serial SD card adapter ! Dreamcast<br /> with IDE/CF drive ! Computer<br /> with special DVD-ROM drive |- |Retail GD-ROM |Yes, using [[httpd-ack]] |Yes, using [[SDRip]] |Yes, but [[DreamShell]] dumps unreliable |Yes, using [http://wiki.redump.org/index.php?title=GD-Rom_Dumping_Guide Redump method] |- |GD-R<br />(3-track style) |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick<br />(but [[DreamShell]] dumps unreliable) |No |- |GD-R<br />(>3 tracks with audio) |Yes, with [[System Disc 2]], OR<br />Yes, with complicated swap trick |Yes, but only with [[System Disc 2]] |Yes, but only with [[System Disc 2]]<br />(but [[DreamShell]] dumps unreliable) |No |- |} 3a3c416e82c9f81938e0a11e09722c5292540c45 1814 1813 2023-01-05T21:10:48Z Unknown user 0 wikitext text/x-wiki Dumping [[GD-ROM|GD-ROMs]] can be done using a Dreamcast console with a [[Serial SD card adapter]], [[Broadband adapter]], or [[LAN adapter]]. Alternative, special models of PC drives can be disassembled and modified to dump GD-ROMs with the proper software and technique. If you have a Broadband Adapter, the simplest way is using [[httpd-ack]] ([[:File:Httpd-ack-20080711.zip|download]]). If you are using an SD card adapter, use [[SDRip]] ([[:File:Dcsdrip11.zip|download]]). GD-ROM images are most commonly stored in the [[GDI format]]. {| class="wikitable" |+Methods for dumping and types of discs possible to dump |- ! ! Dreamcast<br /> with Broadband/LAN adapter ! Dreamcast<br /> with serial SD card adapter ! Dreamcast<br /> with IDE/CF drive ! Computer<br /> with special DVD-ROM drive |- |Retail GD-ROM |Yes, using [[httpd-ack]] |Yes, using [[SDRip]] |Yes, using [[DreamShell]] |Yes, using [http://wiki.redump.org/index.php?title=GD-Rom_Dumping_Guide Redump method] |- |GD-R<br />(3-track style) |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |Yes, with [[System Disc 2]], OR<br />Yes, with simple swap trick |No |- |GD-R<br />(>3 tracks with audio) |Yes, with [[System Disc 2]], OR<br />Yes, with complicated swap trick |Yes, but only with [[System Disc 2]] |Yes, but only with [[System Disc 2]]<br /> |No |- |} 1f77c5bdf47d43e9f674d6cda571e9f66f047c6d GD-ROM 0 7 1815 503 2023-01-05T21:15:17Z Unknown user 0 wikitext text/x-wiki The GD-ROM format is Sega's proprietary disc format used for the Sega Dreamcast home console, as well as for the arcade systems [[NAOMI]], [[NAOMI 2]], Triforce, and Chihiro. Holds a [[0GDTEX.PVR]] image that can be shown on the Bios CD player screen. The most common GD-ROM image format is the [[GDI format]]. ==GD-R discs== [[File:GDR discs at Sega.jpg|400px|thumb|right|GD-R discs stored at Sega of America]] GD-R discs are the recordable version of Sega's proprietary disc format. GD-Rs lack the security ring between the standard density and high density sections, and thus only boot on a retail Dreamcast system using a [[System Disc 2]]. The [[Katana Dev.box]] will also play these discs. ec9d9200e210078373fd82534401c2ae38228ba2 VMU development 0 99 1816 1718 2023-01-06T03:49:03Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 1fd3d27a740090969e48d5ba0908da539ad0fbad 1817 1816 2023-01-06T05:59:15Z Unknown user 0 Added Advent Wreath to list of resources wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its repo can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ad332bd932b0914632f15097b07975916e4d9ab6 1818 1817 2023-01-06T06:00:06Z Unknown user 0 /* Advent Wreath */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The Waterbear assembler/disassembler is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can find it [https://github.com/wtetzner/waterbear here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 4bc10416bf59a6a738bd418548636b53c25aacfa File:CLion Edit Configuration.png 6 760 1819 2023-01-06T19:03:13Z Unknown user 0 wikitext text/x-wiki The edit configurations window in CLion 8561a66e596f1e8d0c4e4dffa8b80defc648ba90 File:Remote GDB Server.png 6 761 1820 2023-01-06T19:05:43Z Unknown user 0 wikitext text/x-wiki Shows the option to select Remote GDB Server 060ec7c9c7fb7c9cc8b7a51a10b482ce0a88306c File:SSH Credentials.png 6 762 1821 2023-01-06T19:15:12Z Unknown user 0 wikitext text/x-wiki Showing how to open the credentials window 3f744e49cdf5e42d58dd567f28b44523a7904cc0 File:SSH Credentials Page.png 6 763 1822 2023-01-06T19:16:44Z Unknown user 0 wikitext text/x-wiki Shows the SSH credentials page in CLion d07e59fb5224064b829682cbe6ace30a8a19fa29 CLion Debugging 0 764 1823 2023-01-06T19:30:59Z Unknown user 0 Created page with "This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: *..." wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's Cable]] (serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Remote GDB Debugger": [[File:Remote GDB Server.png|frameless]] == Remote GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable remote debugging sessions. === Setup SSH credentials === CLion handles setting up and running the remote GDB server instance. Unfortunately, it requires running the executable through SSH which means CLion will have to "remotely" login to the same computer to run the dcload session. Once the host system is configured for SSH access, it's as simple as creating a new set of credentials within the debug configuration setup window to allow CLion to access your computer over SSH. First, select the settings cog beside Credentials in the debug configuration: [[File:SSH Credentials.png|frameless]] Create a new set of credentials using the + button and fill in the information to be able to remotely connect to the host system: [[File:SSH Credentials Page.png|frameless]] If dcload will be run from the same system, it should be enough to enter "localhost" as the host and then fill in the user credentials for the user account on the host system. Using the "Test Connection" button should be an indication of whether the host system or credentials have been setup correctly. After saving the new SSH credentials, select them from the "Credentials" dropdown in the debug configuration page. === GDB Configuration Settings === Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Credentials:''' The credentials created in the previous section * '''Upload Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $CMakeProjectDir$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. b10c51ed6d058302198e5475a70785094439e67c 1824 1823 2023-01-06T20:58:30Z Unknown user 0 /* Setup */ wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Remote GDB Debugger": [[File:Remote GDB Server.png|frameless]] == Remote GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable remote debugging sessions. === Setup SSH credentials === CLion handles setting up and running the remote GDB server instance. Unfortunately, it requires running the executable through SSH which means CLion will have to "remotely" login to the same computer to run the dcload session. Once the host system is configured for SSH access, it's as simple as creating a new set of credentials within the debug configuration setup window to allow CLion to access your computer over SSH. First, select the settings cog beside Credentials in the debug configuration: [[File:SSH Credentials.png|frameless]] Create a new set of credentials using the + button and fill in the information to be able to remotely connect to the host system: [[File:SSH Credentials Page.png|frameless]] If dcload will be run from the same system, it should be enough to enter "localhost" as the host and then fill in the user credentials for the user account on the host system. Using the "Test Connection" button should be an indication of whether the host system or credentials have been setup correctly. After saving the new SSH credentials, select them from the "Credentials" dropdown in the debug configuration page. === GDB Configuration Settings === Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Credentials:''' The credentials created in the previous section * '''Upload Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $CMakeProjectDir$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. 200e5d90200742bf2352f3906e49c034ed91d22a 1826 1824 2023-01-06T21:01:52Z Unknown user 0 wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Embedded GDB Debugger": [[File:Embedded GDB Server configuration.png|frameless]] == Remote GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable remote debugging sessions. Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Upload Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $CMakeProjectDir$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. 9bee96e48dfb44331a0dd284819aa1ee2c3545fd 1829 1826 2023-01-06T21:17:20Z Unknown user 0 wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Embedded GDB Debugger": [[File:Embedded GDB Server configuration.png|frameless]] == Embedded GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable debugging sessions. Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable binary:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Download Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $CMakeProjectDir$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. ba1d2b11c482510e92a4daac78a547b75689ae51 1830 1829 2023-01-06T21:18:02Z Unknown user 0 wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Embedded GDB Debugger": [[File:Embedded GDB Server configuration.png|frameless]] == Embedded GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable debugging sessions. Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable binary:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Download Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $ContentRoot$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. c5e150b26ab620ca145f2cd62d8a04ad72cc3ac8 File:Embedded GDB Server configuration.png 6 765 1825 2023-01-06T21:00:23Z Unknown user 0 wikitext text/x-wiki This shows the embedded gdb server option in CLion 1a508605fe550513dc435191b1a49881ba369d77 Modem 0 87 1827 271 2023-01-06T21:03:44Z Unknown user 0 wikitext text/x-wiki The Dreamcast console came packed with a 33.6K or 56K modem in the vast majority of configurations available worldwide. The modem is compatible with more commercial games than the [[Broadband Adapter]], so many people pair it with a [[DreamPi]] to play games online with a modern home broadband connection. There is a good reference on the modem hardware revisions [http://users.skynet.be/t_chan/dc/mylist.htm here]. {{DCWiki:Stub}} 7824ad25a7931e66c545c6e200a3aaaa6abaefd9 1828 1827 2023-01-06T21:03:50Z Unknown user 0 wikitext text/x-wiki The Dreamcast console came packed with a 33.6K or 56K modem in the vast majority of configurations available worldwide. The modem is compatible with more commercial games than the [[Broadband adapter]], so many people pair it with a [[DreamPi]] to play games online with a modern home broadband connection. There is a good reference on the modem hardware revisions [http://users.skynet.be/t_chan/dc/mylist.htm here]. {{DCWiki:Stub}} f9a946a949d06166bceaf8a491f97a9f5fa3e7b4 Development 0 2 1831 1699 2023-01-06T21:20:10Z Unknown user 0 /* Debugging & profiling */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[Save VMU game]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] ab14ac13f2e5e61dce85965fd968896a0c7bcad2 Using Ruby for Sega Dreamcast development 0 262 1832 794 2023-01-06T21:56:42Z Unknown user 0 Updating the build instruction for making mruby. wikitext text/x-wiki It's possible to develop in [https://www.ruby-lang.org Ruby] for the Sega Dreamcast system using the [https://mruby.org/ mruby implementation]. This proof-of-concept was initially made by [[Yuji Yokoo]] back in 2019. This is experimental and a lot of features are missing, not working and/or not tested (e.g. debugging). As almost all Sega Dreamcast software, this uses [[KallistiOS]] (KOS) as base. == Prerequisites == * You should have a working [[KallistiOS]] environment and all the dependencies made for compiling KallistiOS installed; * You need to have [[KallistiOS]] library built; * The ''/opt/toolchains/dc/kos/kernel/build/newlib_kill.o'' and ''/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o'' object files should be on your disk (they are produced when building KOS) - this is actually an issue that should be fixed later; * You need to have ''rake'' and ''bison'' installed (see below). === Installing prerequisites on Cygwin === Open the Cygwin setup and search for the ''rake'' and ''bison'' packages and install them. === Installing prerequisites on DreamSDK (MinGW/MSYS) === If you use the [[DreamSDK]] environment (or your custom [http://mingw.org MinGW/MSYS] environment) you need to install '''Ruby''' for Windows and the additional ''bison'' package. * Install [https://rubyinstaller.org/ RubyInstaller] then verify that the ''rake'' command is available in the ''PATH'' environment variable. * Install ''msys-bison-bin'' package from the '''MinGW Installation Manager''' program. '''Note:''' If you are using DreamSDK on Windows XP, then you should install [https://rubyinstaller.org/ RubyInstaller] 2.0.0 as it the last version which supports this system. === Installing prerequisites on GNU/Linux === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''apt'' with Debian/Ubuntu). === Installing prerequisites on macOS === Install the ''rake'' and ''bison'' packages with your package manager (e.g. ''brew''). === Installing prerequisites on MinGW-w64/MSYS2 === pacman -S rake bison == Setting up mruby == Open a Terminal and type the following: cd /opt git clone https://github.com/mruby/mruby.git cd /opt/mruby make MRUBY_CONFIG=dreamcast_shelf This will generate all the required files, i.e. the host tools plus the embedded mruby library (''libmruby.a'') for the Sega Dreamcast. == Using mruby on a Sega Dreamcast project == Currently, two projects are available as template: * [https://github.com/yujiyokoo/dreampresent Dreampresent]: A simple presentation tool; * [https://github.com/yujiyokoo/mrbtris-dreamcast Mrbtris]: A sample game. Clone these repositories then build these projects by using the usual ''make'' command (of course, this requires '''mruby''' installed properly!). 6cd632d47e3e2931f6c1cd4534e2f7137b900617 Scrambling 0 766 1833 2023-01-06T22:18:51Z Unknown user 0 Created page with "As a form of piracy protection, when booting from [[MIL-CD]] formatted discs, the Dreamcast loads the main program binary specified in the [[IP.BIN]] using a unique "de-scramb..." wikitext text/x-wiki As a form of piracy protection, when booting from [[MIL-CD]] formatted discs, the Dreamcast loads the main program binary specified in the [[IP.BIN]] using a unique "de-scramble" decryption algorithm. Therefore, in order to load a program into memory from disc correctly, the binary must be encrypted using the correct "scramble" algorithm. This process does not apply to programs stored on GD-ROM media. When pirate groups in the [https://en.wikipedia.org/wiki/Warez_scene warez scene] started releasing "self-boot" versions of Dreamcast games, they chose the alternative route of implementing the algorithm inside the [[IP.BIN]], so that the program is stored normally on disc, becomes "de-scrambled" into memory by the system at load time, and then is "re-scrambled" by the injected [[IP.BIN]] code just before execution. A scramble/descramble algorithm was published by Dreamcast hobbyist pioneer [[Marcus Comstedt]] into the public domain. His algorithm is published below. <syntaxhighlight lang="c" line>#include <stdio.h> #include <stdlib.h> #define MAXCHUNK (2048*1024) static unsigned int seed; void my_srand(unsigned int n) { seed = n & 0xffff; } unsigned int my_rand() { seed = (seed * 2109 + 9273) & 0x7fff; return (seed + 0xc000) & 0xffff; } void load(FILE *fh, unsigned char *ptr, unsigned long sz) { if(fread(ptr, 1, sz, fh) != sz) { fprintf(stderr, "Read error!\n"); exit(1); } } void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz) { static int idx[MAXCHUNK/32]; int i; /* Convert chunk size to number of slices */ sz /= 32; /* Initialize index table with unity, so that each slice gets loaded exactly once */ for(i = 0; i < sz; i++) idx[i] = i; for(i = sz-1; i >= 0; --i) { /* Select a replacement index */ int x = (my_rand() * i) >> 16; /* Swap */ int tmp = idx[i]; idx[i] = idx[x]; idx[x] = tmp; /* Load resulting slice */ load(fh, ptr+32*idx[i], 32); } } void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz) { unsigned long chunksz; my_srand(filesz); /* Descramble 2 meg blocks for as long as possible, then gradually reduce the window down to 32 bytes (1 slice) */ for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1) while(filesz >= chunksz) { load_chunk(fh, ptr, chunksz); filesz -= chunksz; ptr += chunksz; } /* Load final incomplete slice */ if(filesz) load(fh, ptr, filesz); } void read_file(char *filename, unsigned char **ptr, unsigned long *sz) { FILE *fh = fopen(filename, "rb"); if(fh == NULL) { fprintf(stderr, "Can't open \"%s\".\n", filename); exit(1); } if(fseek(fh, 0, SEEK_END)<0) { fprintf(stderr, "Seek error.\n"); exit(1); } *sz = ftell(fh); *ptr = malloc(*sz); if( *ptr == NULL ) { fprintf(stderr, "Out of memory.\n"); exit(1); } if(fseek(fh, 0, SEEK_SET)<0) { fprintf(stderr, "Seek error.\n"); exit(1); } load_file(fh, *ptr, *sz); fclose(fh); } void save(FILE *fh, unsigned char *ptr, unsigned long sz) { if(fwrite(ptr, 1, sz, fh) != sz) { fprintf(stderr, "Write error!\n"); exit(1); } } void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz) { static int idx[MAXCHUNK/32]; int i; /* Convert chunk size to number of slices */ sz /= 32; /* Initialize index table with unity, so that each slice gets saved exactly once */ for(i = 0; i < sz; i++) idx[i] = i; for(i = sz-1; i >= 0; --i) { /* Select a replacement index */ int x = (my_rand() * i) >> 16; /* Swap */ int tmp = idx[i]; idx[i] = idx[x]; idx[x] = tmp; /* Save resulting slice */ save(fh, ptr+32*idx[i], 32); } } void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz) { unsigned long chunksz; my_srand(filesz); /* Descramble 2 meg blocks for as long as possible, then gradually reduce the window down to 32 bytes (1 slice) */ for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1) while(filesz >= chunksz) { save_chunk(fh, ptr, chunksz); filesz -= chunksz; ptr += chunksz; } /* Save final incomplete slice */ if(filesz) save(fh, ptr, filesz); } void write_file(char *filename, unsigned char *ptr, unsigned long sz) { FILE *fh = fopen(filename, "wb"); if(fh == NULL) { fprintf(stderr, "Can't open \"%s\".\n", filename); exit(1); } save_file(fh, ptr, sz); fclose(fh); } void descramble(char *src, char *dst) { unsigned char *ptr = NULL; unsigned long sz = 0; FILE *fh; read_file(src, &ptr, &sz); fh = fopen(dst, "wb"); if(fh == NULL) { fprintf(stderr, "Can't open \"%s\".\n", dst); exit(1); } if( fwrite(ptr, 1, sz, fh) != sz ) { fprintf(stderr, "Write error.\n"); exit(1); } fclose(fh); free(ptr); } void scramble(char *src, char *dst) { unsigned char *ptr = NULL; unsigned long sz = 0; FILE *fh; fh = fopen(src, "rb"); if(fh == NULL) { fprintf(stderr, "Can't open \"%s\".\n", src); exit(1); } if(fseek(fh, 0, SEEK_END)<0) { fprintf(stderr, "Seek error.\n"); exit(1); } sz = ftell(fh); ptr = malloc(sz); if( ptr == NULL ) { fprintf(stderr, "Out of memory.\n"); exit(1); } if(fseek(fh, 0, SEEK_SET)<0) { fprintf(stderr, "Seek error.\n"); exit(1); } if( fread(ptr, 1, sz, fh) != sz ) { fprintf(stderr, "Read error.\n"); exit(1); } fclose(fh); write_file(dst, ptr, sz); free(ptr); } int main(int argc, char *argv[]) { int opt = 0; if(argc > 1 && !strcmp(argv[1], "-d")) opt ++; if(argc != 3+opt) { fprintf(stderr, "Usage: %s [-d] from to\n", argv[0]); exit(1); } if(opt) descramble(argv[2], argv[3]); else scramble(argv[1], argv[2]); return 0; }</syntaxhighlight> 6ecd09d25553cde508ba39726134d403917c9989 Fan replacement 0 767 1834 2023-01-06T22:28:08Z Unknown user 0 Created page with "The Dreamcast is notorious for its loud operation thanks to both a loud fan and a noisy [[GD-ROM drive]] mechanism. Enthusiasts now frequently replace the fan with a Noctua NF..." wikitext text/x-wiki The Dreamcast is notorious for its loud operation thanks to both a loud fan and a noisy [[GD-ROM drive]] mechanism. Enthusiasts now frequently replace the fan with a Noctua NF-A4x10 5V fan, which is near-silent in operation. In order to facilitate the replacement, a 3D-printed bracket is used alongside a 3D-printed replacement "Open" lid mechanism to allow for the proper mounting and clearance of the fan. In addition, an adapter cable with a resistor must be used for the fan to connect and send the proper fan-sense signal to the Dreamcast motherboard, otherwise the system will refuse to operate without detecting a fan. A premade kit for this is available at [https://www.laserbear.net/products/noctua-nf-a4x10-5v-bulk-packaging Laser Bear Industries] and other online stores. 0ac670507dd3366bf9ce56288f9253f8ba21a489 Visual Studio Code 0 768 1835 2023-01-06T22:31:36Z Unknown user 0 Created page with "This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Setup Build..." wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> f6ca9c83b50481341b2bb6ae7f9792a53656207a DCWiki:Hardware 4 82 1836 1002 2023-01-06T22:41:58Z Unknown user 0 wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCDigital]] HDMI, [[S/PDIF]], [[Internal VGA]], [[MIDI expansion|MIDI]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]], [[32MB RAM expansion]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} f9b09e42b0c09433dab32406caafb68c100648f0 Getting Started with Dreamcast development 0 694 1837 1779 2023-01-06T23:02:04Z Unknown user 0 /* Starting the compilation */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make This will take a bunch of hours, then the toolchains will be ready. Please note, this command won't build the GNU Debugger (gdb). To install it, you may enter the following: make gdb =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 8942b3e6f135085e1e82fe77caeabf3b81a4d39e 1838 1837 2023-01-06T23:04:06Z Unknown user 0 /* Starting the compilation */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make This will take a bunch of hours, then the toolchains will be ready. Please note, the above command won't build the GNU Debugger (gdb) for the Dreamcast. To install it, you need to enter the following: make gdb The GNU Debugger is now installed aside your toolchains. =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. f7c07f854c9ec9a5352daa72b4d5373721416d5e Getting Started with Dreamcast development 0 694 1839 1838 2023-01-06T23:05:15Z Unknown user 0 /* Starting the compilation */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. It is highly recommended to set makeopts=-j1, as on some operating systems the toolchain may fail to build with a higher setting. ===Finally, compiling the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Starting the compilation=== Compile the toolchain: make This will take a bunch of hours, then the toolchains will be ready. Please note, the above command won't build the GNU Debugger (gdb) for the Dreamcast. To install it, you need to enter the following: make gdb The GNU Debugger is now installed aside your toolchains. ===Cleaning up temporary files=== After building everything, you can cleanup easilly your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 2f559db0c3cfb1f95b75ba2398fd9b5dcf5c2256 1877 1839 2023-01-26T15:57:31Z Unknown user 0 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, whereas the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.stable.sample config.mk mv config.mk.testing.sample config.mk Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 8924ab4342f18edcd9aab417f114a993559652bd 1883 1877 2023-02-04T07:10:13Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''latest''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''testing''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''stable''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''latest'' version unless you run into an issue. Run one of the following two commands to make your choice: mv config.mk.latest.sample config.mk mv config.mk.testing.sample config.mk mv config.mk.stable.sample config.mk Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 9e25e1a5eeb34901bb13e352ba45a007b18c3d54 1884 1883 2023-02-04T07:21:51Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''latest''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''latest'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following two commands to make your choice: mv config.mk.latest.sample config.mk mv config.mk.testing.sample config.mk mv config.mk.stable.sample config.mk Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. f4a8fd2668dbe11d3a043792992d5009b675eda9 1886 1884 2023-02-12T18:02:16Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''latest''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''latest'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following two commands to make your choice: mv config.mk.testing.sample config.mk (GCC 12.2) mv config.mk.stable.sample config.mk (GCC 9.3) mv config.mk.legacy.sample config.mk (GCC 4.7) Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. a1a606d646396ae4a6abf514353b055d4aab5257 1887 1886 2023-02-12T18:02:40Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''latest''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following two commands to make your choice: mv config.mk.testing.sample config.mk (GCC 12.2) mv config.mk.stable.sample config.mk (GCC 9.3) mv config.mk.legacy.sample config.mk (GCC 4.7) Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. aad58a63bea7632b5758e37bf4159e213915e493 1888 1887 2023-02-12T18:05:32Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''latest''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following two commands to make your choice: '''(GCC 12.2):''' mv config.mk.testing.sample config.mk '''(GCC 9.3):''' mv config.mk.stable.sample config.mk '''(GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. d541566591ee0dd405a4b93fad529a3ab278360a 1890 1888 2023-02-12T18:07:17Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''latest''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following two commands to make your choice: '''(GCC 12.2):''' mv config.mk.testing.sample config.mk '''(GCC 9.3):''' mv config.mk.stable.sample config.mk '''(GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 82bc989afd60b8fc7fe4fa0e4eb4be6d3eda8d61 1891 1890 2023-02-16T17:53:28Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 1c96e1fd9cee09a5c7a9c6f9df3a82055fcb2867 Using dcload-ip with Linux 0 37 1840 982 2023-01-06T23:31:54Z Unknown user 0 /* Dreamcast side */ wikitext text/x-wiki =Linux: using dcload-ip with the BBA= This tutorial has been tested on a new Linux Mint 19.1 install and Windows Subsystem for Linux (WSL). My Dreamcast is connected directly to my computer, with no router in between, using dcload-ip with a hardcoded static IP address. ==Dreamcast side== [[:File:Dcload-2022-12-17.zip|Get a selfbooting version of dcload-ip]]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA MAC address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ==Computer side (not necessary if using pre-built DHCP version)== We'll use the arp fonction to get your computer to "give" an IP address to your Dreamcast based on its mac address. In a terminal, enter: <syntaxhighlight lang="bash">sudo arp -s [IP address] [MAC address]</syntaxhighlight> *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast *<code>[MAC address]</code> is your dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ==Testing your code== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ==Notes (for non-DHCP use)== ===arp=== The arp command used on step 3 will need to be entered every time you re log/shut down the dreamcast. I've added it to my <code>environ.sh</code> script. ===Adding a host name=== Also, you can add a line to your host file in order to replace [local IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> 0198f3e39a398efc1d563bc85394f05d3788347f Using dcload-ip with Windows Subsystem for Linux 0 264 1841 984 2023-01-06T23:32:13Z Unknown user 0 /* Dreamcast side */ wikitext text/x-wiki =WSL v2: using dcload-ip with the BBA from WSL and Windows= This tutorial has been tested on Windows 10 and Windows Subsystem for Linux (WSL) v2. My Dreamcast is connected directly to a router that is also connected to my computer, the router is not plugged into anything else, and does not having greater network access, and using dcload-ip with a hardcoded static IP address. ==Dreamcast side== [[:File:Dcload-2022-12-17.zip|Get a selfbooting version of dcload-ip]]. I've burned this with [https://www.instructables.com/id/Dreamcast-Burn-Games-with-ImgBurn/ imgburn] without any problem. Next, boot '''dc-load-ip''' in your Dreamcast and make sure your BBA is connected in order to get your BBA MAC address. Once the green screen appears, note down your MAC address. It should look something like: <code>10:04:5d:2b:0f:4d</code> ==Computer side (not necessary if using pre-built DHCP version)== We'll use the arp function to get your computer to "give" an IP address to your Dreamcast based on its MAC address. ===Under a Windows Terminal=== First we need Administrator access to add an arp entry. <syntaxhighlight lang="powershell">Start-Process PowerShell –Verb RunAs</syntaxhighlight> After you have this PowerShell instance open we will add our entry: <syntaxhighlight lang="powershell">New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "[IP address]" -LinkLayerAddress "[MAC address]"</syntaxhighlight> *If using Wifi, the interface alias is likely <code>"Wi-Fi"</code> This is the command I use: <syntaxhighlight lang="powershell">New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F"</syntaxhighlight> This should be fairly straightword to modify for your needs and network setup. This will be a permanent addition which will persist across restarts and shutdowns. Expected Output: <pre>PS C:\WINDOWS\system32> New-NetNeighbor -InterfaceAlias "Ethernet" -IPAddress "192.168.2.200" -LinkLayerAddress "00-D0-F1-02-5E-8F" ifIndex IPAddress LinkLayerAddress State PolicyStore ------- --------- ---------------- ----- ----------- 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent ActiveStore 18 192.168.2.200 00-D0-F1-02-5E-8F Permanent PersistentStore</pre> ==Notes== *<code>[IP address]</code> is any valid IP address that you want to assign to your Dreamcast. *<code>[MAC address]</code> is your Dreamcast's MAC address, look at step 2. The IP address should be in the same range as your local network. In my setup, my ethernet port is set on port 192.168.5.100 and my <code>[IP address]</code> is 192.168.5.99. If you don't know your network range, you can use <code>ifconfig</code> in a terminal to find out. I won't cover this here. ==The following can be executed from within Windows or WSL (Linux)== At this point, you should be able to see if your Dreamcast is connected. A simple ping command should do the job. <syntaxhighlight lang="bash">ping [IP address]</syntaxhighlight> You should get a message like: ''64 byte from [IP address] .... blabla ... time=xx ms'' ===Testing your code=== You can now use the dc-tool-ip program to send your file to the DC. Make sure your Dreamcast is running '''dc-load-ip'''. <syntaxhighlight lang="bash">dc-tool-ip -t [IP address] -x /path/to/your/.bin/or/.elf/file</syntaxhighlight> You can always run dc-tool-ip without any command to get some info on how to run it. The -c option is useful if you need to use files that are located on your pc. You can use them with the '/pc' path. ==Notes (for non-DHCP use)== ===Adding a host name (Linux)=== Also, you can add a line to your host file in order to replace [IP address] to a more friendly name. <syntaxhighlight lang="bash">sudo nano /etc/hosts</syntaxhighlight> then adding the line: <code>dreamcast [IP address]</code> ===Adding a host name (Windows)=== # Press the Windows key. # Type Notepad in the search field. # In the search results, right-click Notepad and select Run as administrator. # From Notepad, open the following file: <code>c:\Windows\System32\Drivers\etc\hosts</code> # Add a new entry to the file. e.g. <code>dreamcast [IP address]</code> on a newline # Select File > Save to save your changes. You can now refer to <code>dreamcast</code> instead of your usual <code>[IP address]</code> d00fe4b3a9763bd9aef68f37270b99240889f087 Tools and Utilities 0 131 1842 793 2023-01-06T23:33:34Z Unknown user 0 wikitext text/x-wiki This article will list various tools and utilities for Dreamcast development and game hacking. == Loaders == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[dcload-ip]] || Boot your applications via [[Broadband adapter]] || |- | [[dcload-serial]] || Boot your applications via [[Coder's cable]] || |} == CD utilities == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[dcdis]] || || |- | [[mkisofs]] || Bundle your project directory into a .iso || |- | [[cdi4dc]] || Create bootable .CDI files || |- | [[img4dc]] || Updated version of cdi4dc || |- | [[GD-ROM Explorer]] || Extract and manipulate GD-ROM images in GDI format || |} == Texture converter == {| class="wikitable" style="width: 100%;" |- ! Name !! Description !! Link |- | [[Texconv]] || Convert your texture to the .dtex format || [https://github.com/tvspelsfreak/texconv Github] |- | [[Crayon Utilities]] || VMU and RGBA888 image conversion || [https://github.com/Protofall/Crayon-Utilities Github] |} {{DCWiki:Stub}} 96bf99ce431944dd0e6e0da205e0eb4dd5665486 32MB RAM expansion 0 284 1843 1780 2023-01-07T06:01:57Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issue is Sofdec video playback in commercial games. These games will fail to play FMV, often hanging or crashing as a result. More research is needed to determine if this issue can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> KallistiOS also includes [https://github.com/KallistiOS/KallistiOS/tree/master/examples/dreamcast/basic/memtest32 memtest32] in its example programs. Adapted from tsowell's original utility, memtest32 supports memory testing 16MB and 32MB Dreamcasts. ===DreamShell=== The latest version of the [[DreamShell]] operating system, which uses KallistiOS as its kernel, now supports 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X ==Emulators== ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when run with the <code>--ram-size=32</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir meson compile -C builddir ./builddir/lxdream-nitro --ram-size=32 58a8c36793a16f330fc786720f2bfc1a39fe4391 File:VMU.pdf 6 100 1844 1548 2023-01-07T09:27:09Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer but are crucial for emulation. === Errors === * The first example for the DIV instruction stores the wrong value in the accumulator. Look at the table instead of the code. * There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." 53aa1136263db899e118204af883b6eded5d3b41 1845 1844 2023-01-07T09:28:59Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer but are crucial for emulation. === Errors === * The first example for the DIV instruction stores the wrong value in the accumulator. It should be 0x79 instead of 0x78. * There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." ec974b659eecd227b74742ce71cdf5df493b3358 1878 1845 2023-01-29T20:42:39Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer but are crucial for emulation. === Errors === * The first example for the DIV instruction stores the wrong value in the accumulator. It should be 0x79 instead of 0x78. * There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." * Example 2 for JMP a12 on page VMC-197 has the wrong instruction code for the instruction "JMP LA." 38fef869e5a343ce059c1f72a5c592ec79230adc 1879 1878 2023-01-29T20:44:27Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer but are crucial for emulation. === Errors === * The first example for the DIV instruction stores the wrong value in the accumulator. It should be 0x79 instead of 0x78. * There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." * The Instruction Code for LD d9 on page VMC-186 is incorrect. * Example 2 for JMP a12 on page VMC-197 has the wrong instruction code for the instruction "JMP LA." 2318af5e15c83bc85e6d606660956eac22107032 1880 1879 2023-01-29T20:53:43Z Unknown user 0 wikitext text/x-wiki == Summary == Official application developer's manual for the Visual Memory Unit. * Tutorial Manual * Specifications * Hardware Manual * Programing Manual * VMU-BIOS Specifications * Sound Development Specifications * Simulator Manual === Limitations === Due to the fact the VMU features a built-in BIOS handling OS-specific tasks, the documentation is lacking in a few low-level places, such as hidden instructions and internal SFRs. These are areas that should not concern a typical application developer but are crucial for emulation. === Errors === * The first example for the DIV instruction stores the wrong value in the accumulator. It should be 0x79 instead of 0x78. * There are also many places with typos, where a register bit is referenced as being "set to 0" and "reset to 0," when it should say "set to 1" or "reset to 0." * The Instruction Code for LD d9 on page VMC-186 is incorrect. 438cb9cba78f9648d609f3ff08f66b61b08e17e7 File:CLion Debug Icon.png 6 769 1846 2023-01-07T18:23:13Z Unknown user 0 wikitext text/x-wiki This shows the debug icon in the toolbar of CLion 5a85fafeee392b64991b2bdcb682cf90e02717ff File:CLion Breakpoint.png 6 770 1847 2023-01-07T18:28:14Z Unknown user 0 wikitext text/x-wiki This shows a set breakpoint in the CLion user interface 93ac69be7c47c623205e535f7f1c4d88c96af8af CLion Debugging 0 764 1848 1830 2023-01-07T18:32:17Z Unknown user 0 wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Embedded GDB Debugger": [[File:Embedded GDB Server configuration.png|frameless]] == Embedded GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable debugging sessions. Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable binary:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Download Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $ContentRoot$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. == Using the Debugger == Now that the Embedded GDB Server has been configured, the executable can be launched. To launch a binary on the Dreamcast, make sure it is powered on and dcload-ip/serial has been booted and connected to the computer. Once the Dreamcast is ready to receive a new binary, click on the "bug" icon in the toolbar of CLion: [[File:CLion Debug Icon.png|frameless]] This will compile any changes and generate a new .elf file and launch dc-tool-[ip/ser] with the correct flags. The desired binary should be deployed to and launched on the Dreamcast at this point. The dc-tool-* binary should now be waiting for a GDB connection. CLion will launch GDB and connect to the waiting GDB server. Once CLion connects, a debug session will be started in the CLion user interface. === Creating breakpoints === Creating breakpoints in CLion is as easy as a single click. To set a breakpoint, hover over a line number within a file and a small red circle will appear. The specific line the program should stop at can be clicked: [[File:CLion Breakpoint.png|frameless]] 0fffc406a1d79a1bceef264a57de2fc3fd8f4e53 1858 1848 2023-01-09T16:13:59Z Unknown user 0 wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected * SSH must be configured for remote logins on the host system == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Embedded GDB Debugger": [[File:Embedded GDB Server configuration.png|frameless]] == Embedded GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable debugging sessions. Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable binary:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Download Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $ContentRoot$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. == Using the Debugger == Now that the Embedded GDB Server has been configured, the executable can be launched. To launch a binary on the Dreamcast, make sure it is powered on and dcload-ip/serial has been booted and connected to the computer. Once the Dreamcast is ready to receive a new binary, click on the "bug" icon in the toolbar of CLion: [[File:CLion Debug Icon.png|frameless]] This will compile any changes and generate a new .elf file and launch dc-tool-[ip/ser] with the correct flags. The desired binary should be deployed to and launched on the Dreamcast at this point. The dc-tool-* binary should now be waiting for a GDB connection. CLion will launch GDB and connect to the waiting GDB server. Once CLion connects, a debug session will be started in the CLion user interface. Below are some of the features supported by CLion's debugger: === Breakpoints === To set a breakpoint, hover over a line number within a file and a small red circle will appear. The breakpoint can be enabled or disabled by clicking the red circle: [[File:CLion Breakpoint.png|frameless]] === Stdout capturing === The debug view within can show the output of dc-tool: [[File:Stdout capture.png|frameless]] === Memory viewer === CLion can take a memory location as an input and display the data at that point in memory: [[File:CLion memory viewer.png|frameless]] === Display type data on hover === While debugging in a breakpoint, the user can hover over variables within a method to display their contents: [[File:Hover variable.png|frameless]] === View pointers as arrays === Pointers can be displayed as arrays by right-clicking on the specific variable in the variable viewer and selecting "View as Array...": [[File:View as Array.png|frameless]] The user interface will ask for the size of the array. Once the size has been input, CLion will display the variable as an array of that type: [[File:View as array output.png|frameless]] 70ccd88374e5dc62bb40ad3ddd8324b73b1119ad 1859 1858 2023-01-09T16:18:01Z Unknown user 0 Removed SSH requirement wikitext text/x-wiki This guide will help with setting up CLion for remote debugging through dcload's GDB feature. == Setup == The following criteria must be met before following this guide: * The specific project must be [[Dreamcast_CMake_Project_In_CLion|setup within CLion]] * A working version of [[dcload-ip]] or [[dcload-serial]] must be available on the host system * The target Dreamcast will need either a [[Broadband adapter]], [[LAN adapter]], or a [[Coder's cable]] (USB or serial cable) connected == Creating a debug configuration == After opening your project in CLion, click the dropdown for the current debug/run configuration and select "Edit Configurations...": [[File:CLion Edit Configuration.png|frameless]] In the configuration editor window, select the + icon to create a new configuration and select "Embedded GDB Debugger": [[File:Embedded GDB Server configuration.png|frameless]] == Embedded GDB Server Settings == Now that the new configuration has been created, the specific settings can now be populated to enable debugging sessions. Use the following settings in the debug configuration page: * '''Name:''' Dreamcast Debug IP/Serial (really, it's up to the user) * '''Target:''' Your project * '''Executable binary:''' Your executable for your project * '''GDB:''' Bundled GDB (This can handle SH-4 executables) * '''Download Executable:''' Never * ''''target remote' args:''' localhost:2159 (default port for dcload's GDB instance) * '''GDB Server:''' /path/to/dc-tool-[ip|serial] * '''GDB Server args:''' -g -x $CMakeCurrentBuildDir$/<your executable name>.elf -c $ContentRoot$ -t <IP address or /dev/tty device> :* -g: Starts dcload with GDB :* -x: Uploads and executes your binary :* -c: Points dcload to your project directory to be able to load files with "/pc/" (requires superuser) :* -t: The device dcload should target * '''Advanced GDB Server Options''' :* Run with root privileges: Checked Once all settings have been configured, click "Apply" and the configuration should be ready. == Using the Debugger == Now that the Embedded GDB Server has been configured, the executable can be launched. To launch a binary on the Dreamcast, make sure it is powered on and dcload-ip/serial has been booted and connected to the computer. Once the Dreamcast is ready to receive a new binary, click on the "bug" icon in the toolbar of CLion: [[File:CLion Debug Icon.png|frameless]] This will compile any changes and generate a new .elf file and launch dc-tool-[ip/ser] with the correct flags. The desired binary should be deployed to and launched on the Dreamcast at this point. The dc-tool-* binary should now be waiting for a GDB connection. CLion will launch GDB and connect to the waiting GDB server. Once CLion connects, a debug session will be started in the CLion user interface. Below are some of the features supported by CLion's debugger: === Breakpoints === To set a breakpoint, hover over a line number within a file and a small red circle will appear. The breakpoint can be enabled or disabled by clicking the red circle: [[File:CLion Breakpoint.png|frameless]] === Stdout capturing === The debug view within can show the output of dc-tool: [[File:Stdout capture.png|frameless]] === Memory viewer === CLion can take a memory location as an input and display the data at that point in memory: [[File:CLion memory viewer.png|frameless]] === Display type data on hover === While debugging in a breakpoint, the user can hover over variables within a method to display their contents: [[File:Hover variable.png|frameless]] === View pointers as arrays === Pointers can be displayed as arrays by right-clicking on the specific variable in the variable viewer and selecting "View as Array...": [[File:View as Array.png|frameless]] The user interface will ask for the size of the array. Once the size has been input, CLion will display the variable as an array of that type: [[File:View as array output.png|frameless]] 7689ffed57705083f366d7256c38d4e64c300f8d Maple bus 0 113 1849 1761 2023-01-07T23:51:13Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || MSB: Region code <br> 2 least significant bytes: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8c65e64284f298f7188ded82a8f92919d2d6232c 1850 1849 2023-01-08T00:06:32Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || Device->Host || 0 || - |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8636adcafe7b202534e335ec2f3b4c7661ae03c9 1866 1850 2023-01-14T15:08:19Z Unknown user 0 Correction: the Request Resend command may be sent from either device or host wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0..255 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> f58ee6f9b07b10f9df541ab6f9a20ab37ce3c34c 1867 1866 2023-01-14T16:34:12Z Unknown user 0 The request resend command has no payload wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8f6a3c024f187645c9db89dfc4acf1fbbd4da252 1868 1867 2023-01-14T16:36:56Z Unknown user 0 Added AR Error and LCD Error to list of commands wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 0d8df5a97cfa9ac7e8966e18a267927343cc2898 1869 1868 2023-01-14T16:42:38Z Unknown user 0 Added dreamcast-docs reference wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA. ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 7b99ccebb55c9e43c2da473abf1e1e5f65964880 1870 1869 2023-01-14T16:52:51Z Unknown user 0 Added note that current values are oddly transmitted as big-endian values wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte values are '''transmitted as big-endian''' ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte values are '''transmitted as big-endian''' ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 4638a9b08a86e0f227f80eea2fee2a0b58253ba3 1871 1870 2023-01-14T16:53:38Z Unknown user 0 Fixed bad grammar wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte values is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 754338a5ef7f900a9f8f112f52a6d79e19643add 1872 1871 2023-01-14T16:54:21Z Unknown user 0 Fixed bad grammar again wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> ba3f5049a92587468a143c26705fd8af96864414 1873 1872 2023-01-14T16:56:46Z Unknown user 0 Missed an asterisk here wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> fee4ef54f25e5d88ae4fcaed9bcedf5f3f61357b 1875 1873 2023-01-15T15:58:48Z Unknown user 0 /* Get Memory Information Payload Structure (cmd 0x0A) */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and with about 110 microsecond delays between each 3-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8b36dfda80d28bd6cb43484d71d2cb77b886aff8 Libronin 0 167 1851 576 2023-01-09T01:42:05Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=posix # single threading or posix threads. posix threads might not successfully build for some languages auto_fixup_sh4_newlib=0 # Set this 0 to ensure raw toolchain with no patches Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. '''Do not''' use <code>make</code> alone or the build script will patch the toolchain with KOS patches, which is not what we want here! make build You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 9972fb7e40ede7270ba755cbdb4aa797c60f5b0a 1852 1851 2023-01-09T02:33:44Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=posix # single threading or posix threads. posix threads might not successfully build for some languages auto_fixup_sh4_newlib=0 # Set this 0 to ensure raw toolchain with no patches Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. '''Do not''' use <code>make</code> alone or the build script will patch the toolchain with KOS patches, which is not what we want here! make build You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 49f5c9d4a504a300452dbe27035bb3a7df10b0db 1881 1852 2023-01-31T15:31:15Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads auto_fixup_sh4_newlib=0 # Set this 0 to ensure raw toolchain with no patches Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. '''Do not''' use <code>make</code> alone or the build script will patch the toolchain with KOS patches, which is not what we want here! make build You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} f55581b872bae903d3a1f74ef5fa585b185668e2 File:Stdout capture.png 6 771 1853 2023-01-09T16:07:58Z Unknown user 0 wikitext text/x-wiki This shows the stdout capture in CLion 0f603e6745fc0699cc333c073d400d1b3af70f51 File:CLion memory viewer.png 6 772 1854 2023-01-09T16:10:05Z Unknown user 0 wikitext text/x-wiki This shows the memory viewer within CLion 12ce13dead71030916c520d816e7b1b5d9a13333 File:View as Array.png 6 773 1855 2023-01-09T16:11:31Z Unknown user 0 wikitext text/x-wiki This shows the View as Array... option in CLion c1370843d7ad06c20eee0ee29785359d320bb47f File:View as array output.png 6 774 1856 2023-01-09T16:12:35Z Unknown user 0 wikitext text/x-wiki This shows CLion displaying a pointer as an array f0c99f132e2ed2fdc77da5082b3e5e2ce0b59fa4 File:Hover variable.png 6 775 1857 2023-01-09T16:13:54Z Unknown user 0 wikitext text/x-wiki This shows the variable view tooltip in CLion fc283b3987693aeb9f7734aadd3b287be1d18c74 VMU development 0 99 1860 1818 2023-01-09T17:01:17Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== LC86k Assembly Code ==== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. You can download it [https://github.com/wtetzner/waterbear/releases/latest here]. ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== C Code ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ef9059d707ce9a0e18da9bca9c7479266638c6ff 1861 1860 2023-01-09T17:21:30Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 0e9c7438dd0f8ecd31e7f93bc83e55cc1775d56a 1862 1861 2023-01-09T17:26:39Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] * ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * VMU Tool * DreamShell * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 8a6ada150931ea44f1e1223e7e75c225123f107a 1863 1862 2023-01-09T18:32:05Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] * ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual f257ab02816a75030edfc88772b2af84d777c214 1876 1863 2023-01-26T14:19:47Z Unknown user 0 Added Sublime Text Syntax Definition wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] * ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual a417bee127e88c031a2a37d01818079c1adcf772 Memory map 0 105 1864 507 2023-01-13T18:06:19Z Unknown user 0 /* Physical address format */ wikitext text/x-wiki = Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming: Memory Map, Marcus Comstedt</ref> When the built-in MMU is active, the mapping between logical and physical address is basically left up to the programmer (see the SH4 Hardware Manual for details), however the normal mode of operation in the Dreamcast is to have the MMU disabled, in which the mapping is fixed as described below. = Logical address format= When the MMU is disabled, the 32-bit logical addresses have the following format: {| class=wikitable ! 31 ! 30 ! 29 ! 28 ... 0 |- | P | ALT | NC | Physical address |} === Modifier Bits === In addition to the physical address, the following modifier bits are used: {|class=wikitable ! P | Privileged Access | Addresses with the P bit set can only be accessed when the CPU is running in privileged mode, that is when the MD bit in the status register is set. An exception to this is the Store Queue though. P inhibits the MMU, and enables the ALT and NC bits. If P is not set, ALT and NC are ignored. |- ! ALT | Alternate Address Space | Setting this bit gives an alternate mapping of the physical address bits. If NC is also set, the builtin CPU I/O registers are selected. If NC is not set, MMU translation is selected (if MMU is enabled) even though P is set. |- ! NC | Not Cacheable | Setting this bit circumvents the data cache, which is useful for accessing external hardware registers. |} === Modifier Bit Combinations === The following table shows the possible combinations of the modifier bits: {|class=wikitable !P !ALT !NC !Address range !Description !Area name |- |0 |X |X |0x00000000-0x7FFFFFFF (Physical address space repeats 4 times) |Address translation through MMU (if enabled). Can be accessed in both User and Privileged mode. |U0/P0 |- |1 |0 |0 |0x80000000-0x9FFFFFFF |Privileged mode only. |P1 |- |1 |0 |1 |0xA0000000-0xBFFFFFFF |Privileged mode only, no cache. |P2 |- |1 |1 |0 |0xC0000000-0xDFFFFFFF |Privileged mode only. Address translation through MMU (if enabled). |P3 |- |1 |1 |1 |0xE0000000-0xFFFFFFFF |Privileged mode only. Internal I/O register access. No cache. |P4 |} ==Physical address format== With exception of the P4 area, the different logical address areas share the same physical address space. This address space (of 29 bits) is divided into eight different areas of 64MB size each. {|class=wikitable !Physical address !Contents !Name |- |0x00000000-0x03FFFFFF |Boot ROM (2MB) Flash ROM (256K) Hardware registers |Area 0 |- |0x04000000-0x07FFFFFF |[[Video RAM]] (8MB) |Area 1 |- |0x08000000-0x0BFFFFFF | |Area 2 |- |0x0C000000-0x0FFFFFFF |System RAM (16MB) |Area 3 |- |0x10000000-0x13FFFFFF |Tile accelerator command input |Area 4 |- |0x14000000-0x17FFFFFF |Expansion (modem) port |Area 5 |- |0x18000000-0x1BFFFFFF | |Area 6 |- |0x1C000000-0x1FFFFFFF |Internal I/O registers (same as P4) |Area 7 |} Accesses to Area 7 require the CPU to be running in privileged mode even if the access is through U0. ==References== <references/> 906dceae7224d4b1f242b7ac90dfb73c7c02b63b 1865 1864 2023-01-13T18:08:54Z Unknown user 0 /* Modifier Bit Combinations */ wikitext text/x-wiki = Introduction = The Dreamcast uses 32-bit logical addresses, but the physical address range is only 29-bit. <ref>''[http://mc.pp.se/dc/memory.html]'', Dreamcast Programming: Memory Map, Marcus Comstedt</ref> When the built-in MMU is active, the mapping between logical and physical address is basically left up to the programmer (see the SH4 Hardware Manual for details), however the normal mode of operation in the Dreamcast is to have the MMU disabled, in which the mapping is fixed as described below. = Logical address format= When the MMU is disabled, the 32-bit logical addresses have the following format: {| class=wikitable ! 31 ! 30 ! 29 ! 28 ... 0 |- | P | ALT | NC | Physical address |} === Modifier Bits === In addition to the physical address, the following modifier bits are used: {|class=wikitable ! P | Privileged Access | Addresses with the P bit set can only be accessed when the CPU is running in privileged mode, that is when the MD bit in the status register is set. An exception to this is the Store Queue though. P inhibits the MMU, and enables the ALT and NC bits. If P is not set, ALT and NC are ignored. |- ! ALT | Alternate Address Space | Setting this bit gives an alternate mapping of the physical address bits. If NC is also set, the builtin CPU I/O registers are selected. If NC is not set, MMU translation is selected (if MMU is enabled) even though P is set. |- ! NC | Not Cacheable | Setting this bit circumvents the data cache, which is useful for accessing external hardware registers. |} === Modifier Bit Combinations === The following table shows the possible combinations of the modifier bits: {|class=wikitable !P !ALT !NC !Address range !Description !Area name |- |0 |X |X |0x00000000-0x7FFFFFFF<br />(Physical address space repeats 4 times) |Privileged mode or user mode.<br />Address translation through MMU (if enabled). |U0/P0 |- |1 |0 |0 |0x80000000-0x9FFFFFFF |Privileged mode only. |P1 |- |1 |0 |1 |0xA0000000-0xBFFFFFFF |Privileged mode only, no cache. |P2 |- |1 |1 |0 |0xC0000000-0xDFFFFFFF |Privileged mode only. Address translation through MMU (if enabled). |P3 |- |1 |1 |1 |0xE0000000-0xFFFFFFFF |Privileged mode only. Internal I/O register access. No cache. |P4 |} ==Physical address format== With exception of the P4 area, the different logical address areas share the same physical address space. This address space (of 29 bits) is divided into eight different areas of 64MB size each. {|class=wikitable !Physical address !Contents !Name |- |0x00000000-0x03FFFFFF |Boot ROM (2MB) Flash ROM (256K) Hardware registers |Area 0 |- |0x04000000-0x07FFFFFF |[[Video RAM]] (8MB) |Area 1 |- |0x08000000-0x0BFFFFFF | |Area 2 |- |0x0C000000-0x0FFFFFFF |System RAM (16MB) |Area 3 |- |0x10000000-0x13FFFFFF |Tile accelerator command input |Area 4 |- |0x14000000-0x17FFFFFF |Expansion (modem) port |Area 5 |- |0x18000000-0x1BFFFFFF | |Area 6 |- |0x1C000000-0x1FFFFFFF |Internal I/O registers (same as P4) |Area 7 |} Accesses to Area 7 require the CPU to be running in privileged mode even if the access is through U0. ==References== <references/> c2798ca71b3fd09348bf78acdaaf6e3893841301 VMU peripheral 0 726 1874 1803 2023-01-15T01:54:42Z Unknown user 0 Added "get media info" command wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions (x + 1) |} === Get Media Info === Execute a [[Maple_bus#Commands|get memory information]] command to get information about the size and locations of some information within the media. On successful execution, a [[Maple_bus#Commands|data transfer]] packet with the following payload will be returned. {| class="wikitable" |- ! Word 0 !! Word 1 !! Word 2 !! Word 3 !! Word 4 !! Word 5 !! Word 6 |- | [[Maple_bus#Function_Codes|Function code]] <br> 0x00000002 || 2 most sig bytes: total size <br> 2 least sig bytes: the partition number of this media || 2 most sig bytes: block number of system area <br> 2 least sig bytes: block number of start of FAT area || 2 most sig bytes: number of FAT blocks <br> 2 least sig bytes: block number of file information || 2 most sig bytes: number of file info blocks <br> 2 least sig bytes: icon number || 2 most sig bytes: block number of save area <br> 2 least sig bytes: number of blocks in save area || execution file info |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * A VMU cannot handle successive block write packets faster than about 10 ms per write ** After such error, the storage functionality acts as if it never received this sequence and never returns a response packet - it may be possible to successfully resend this sequence, but writing a "get last error" command would be necessary before starting over at the first sequence ** The Dreamcast does each read/write sequence on the same cadence as controller polling (about every 16 ms) == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom. The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> 39837cd1f6ad83130c8c503312553b5a25a81684 VMU development 0 99 1892 1876 2023-02-16T20:46:29Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] * ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 4d25cb9d01d6e1a001abd226cda4389fb2295ce4 1893 1892 2023-02-16T21:03:44Z Unknown user 0 Added VMU Racketball wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== VMU Racketball ===== VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/pxcla/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] * ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 447481ecc48a80f659194bd811c39c146b013f5a 1896 1893 2023-02-16T21:17:28Z Unknown user 0 Added VMU Racketball wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/pxcla/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual e703c55b91626b5f45858974ab1b2ef8e6072713 1897 1896 2023-02-16T21:51:39Z Unknown user 0 Added additional links to references, thanks to Travis Paul on Github! wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/pxcla/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== [[File:Dream Animator.jpg|thumb|Dream Animator Tool for creating VMU Animations]] While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual b864b21efec03aa1d19751d8e406c715807823be 1901 1897 2023-02-22T01:42:00Z Unknown user 0 Added BMOVIE and Screen capture wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/pxcla/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 5b47d112b5e83c285de5f324cd2e8f0f9597bbef 1902 1901 2023-02-22T02:06:33Z Unknown user 0 /* BMOVIE */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/pxcla/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual c6a7b74832a4e91b88b4389f75487da75e5730bd 1909 1902 2023-02-27T04:25:56Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual e497bdd1f5ea1935eb73363cbc60581f59c25dd9 1917 1909 2023-03-01T01:31:52Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ==== Tiny3D Engine ==== [[File:Tiny3dEngine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual c7e728cedf5da1ed276ce43655fc0c110dfa0bca 1919 1917 2023-03-01T01:33:52Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ==== Tiny3D Engine ==== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 843a08377695dd3b5797addbc5e82d0d0c0c810b 1920 1919 2023-03-01T01:35:34Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 66b1ce17322315a8e33d36583d7810986d7bf6c7 File:VMU Racketball.gif 6 776 1894 2023-02-16T21:06:13Z Unknown user 0 wikitext text/x-wiki Screencapture of Shirobon's "VMU Racketball" minigame. 745f58f33a06e02bc85e38ff7e43f867e4d81ede File:Racketball2.gif 6 777 1895 2023-02-16T21:16:55Z Unknown user 0 wikitext text/x-wiki Screen Capture of Shirobon's "VMU Racketball" 8dea5cc4e5b8fc296a5874d1611991c1b872b032 Development 0 2 1898 1831 2023-02-18T15:35:17Z Unknown user 0 /* VMU */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Using GCC 9.2.0]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 3fc73cbe3f4321ead44d720d61bd819b179f74ab 1899 1898 2023-02-18T15:38:49Z Unknown user 0 /* Other */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 8d92c42ddefc059aa7d116ddce8472bebd75fcd3 1922 1899 2023-03-01T15:35:35Z Unknown user 0 /* KallistiOS */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 71d88d4b10d805df1eb9ac4f0416c7d30c5c074d File:BMOVE Promo.gif 6 778 1900 2023-02-22T01:11:17Z Unknown user 0 wikitext text/x-wiki Promotional Video for Rockin-B's BMOVIE f19a8a4c2a7e49bb8944fd6eb8dd3955870922ac SH4 in Compiler Explorer 0 733 1903 1704 2023-02-26T04:50:39Z Unknown user 0 Added GCC12 templates wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn "C17 Hello World"] ** [https://godbolt.org/z/61jqhE3zn "C++20 Hello World"] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 [[likely]] and [[unlikely]] attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?p=1059844#p1059844 here]. 797831488f10cd817e226c984bf9ce1bcf7cf728 1904 1903 2023-02-26T04:52:20Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn "C17 Hello World"] ** [https://godbolt.org/z/61jqhE3zn "C++20 Hello World"] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?p=1059844#p1059844 here]. a730499efb7787d3927486c1883d36d0c4fbbc41 1905 1904 2023-02-26T04:53:02Z Unknown user 0 /* Tips and Notes */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn "C17 Hello World"] ** [https://godbolt.org/z/61jqhE3zn "C++20 Hello World"] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. 0411c8c6b4a11878deffaf783b58710978effdde 1906 1905 2023-02-26T04:56:18Z Unknown user 0 /* Convenience Templates */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be scene under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. e0fd98e2f62fc7c884059cef9aba92a0bf0e2180 1907 1906 2023-02-26T05:44:31Z Unknown user 0 Embarrassing typo fix wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. ca6d154baa8a28b381fe5898df4a12c591a1352f GLdc 0 24 1908 964 2023-02-26T19:13:14Z Unknown user 0 wikitext text/x-wiki [https://github.com/Kazade/GLdc GLdc] is an OpenGL implementation for the Dreamcast that is actively developed by Kazade. MrNeo also contributed to the testing and optimisation of GLdc ==Features== Supports most of the OpenGL 1.2 implementation. ==Known Issue== Lighting performance is still being worked on. ==Projects built with GLdc== *[[Simulant|Simulant engine]] *[[Summoning Signals]] *[[nuQuake]] ==Building GLdc== '''Make sure you clone this repo in the <code>$KOS_BASE/addons</code> folder''' cd $KOS_BASE/addons` then `git clone https://github.com/Kazade/GLdc.git Once the folder is cloned mkdir dcbuild cd dcbuild cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchains/Dreamcast.cmake -DCMAKE_BUILD_TYPE=Release .. make You can now link GLdc using <code>-lGLdc</code> f1050a785673c7d3796f79e3ea99421c68160404 Getting Started with Dreamcast development 0 694 1910 1891 2023-02-28T02:17:13Z Unknown user 0 /* Compiling the toolchain */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb ''Important Note for Apple users'': If you chose GCC 12.2, you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 40da82f19d0a8e9caea76fbada642e02c8090a64 1911 1910 2023-02-28T02:25:25Z Unknown user 0 /* Compiling the toolchain */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. e6fa402b2a7181b60ff5876a901a1f044de49602 1912 1911 2023-02-28T02:55:10Z Unknown user 0 /* macOS 13 Ventura on an Intel or Apple Silicon processor */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. e24678ecf357ab5d98714d17b8803cfe9ba432f9 1913 1912 2023-02-28T02:56:38Z Unknown user 0 /* Debian/Ubuntu-based Linux */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 6401239f8975ba18ea80fabdf926e3ad247df2d8 1914 1913 2023-02-28T03:23:58Z Unknown user 0 /* Arch-based Linux */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. be12fb4d5b72b30f7a630e5afa77ceb78863a922 1915 1914 2023-02-28T03:29:12Z Unknown user 0 /* Fedora-based Linux */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 087d965a17bc4f474cd0a293c83c18e510fbbb5c File:Tiny3dEngine.gif 6 779 1916 2023-03-01T01:31:32Z Unknown user 0 wikitext text/x-wiki Screen Capture of The Rockin'-B's "Tiny 3D Engine" for the VMU 756e7c226571fa94a62ddebd5b5234c53bf304b9 File:Tiny 3D Engine.gif 6 780 1918 2023-03-01T01:33:37Z Unknown user 0 wikitext text/x-wiki Screen capture of The Rockin'-B's "Tiny 3D Engine" for the VMU 62694200fc3b24fdb319f64bd435d2d8c8f0c438 KallistiOS 0 21 1921 579 2023-03-01T15:00:37Z Unknown user 0 wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Dan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of libdream, the first free developer library for Dreamcast. libdream was also written by Dan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. [http://sourceforge.net/project/showfiles.php?group_id=23791&package_id=76380&release_id=144971 libdream source] == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] == Documentation == Up-to-date Doxygen-based documentation of KallistiOS is [https://kos-docs.dreamcast.wiki/ available on the wiki]. ae66a260cb2715c005393a3e0d04bdce9315aaeb File:Atari800DC.png 6 782 1924 2023-03-01T19:20:58Z Unknown user 0 wikitext text/x-wiki Atari800DC 019e66d45d6ac5578915e4aeb2d93e9cdf17cb1a Atari800DC 0 783 1925 2023-03-01T19:21:32Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Atari800 DC| image=[[Image:Atari800DC.png|thumb|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]|..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Atari800 DC| image=[[Image:Atari800DC.png|thumb|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]| version=0.78| downloads=[ftp://ftp.groessler.org/pub/chris/dreamcast/atari800dc/0.78/atari800dc-0.78-bin.tar.gz Plainfiles]<br>[ftp://ftp.groessler.org/pub/chris/dreamcast/atari800dc/0.78/atari800dc-0.78.tar.gz Source]| release date=08/17/08| author=[[Captain Skyhawk]]| original=[http://atari800.sourceforge.net/ Atari800]| systems=Atari 400/800/600XL/800XL/etc...| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Atari800 is an emulator for the Atari 8bit machines (400/800/600XL/800XL/etc.) ported to the Dreamcast by [[Captain Skyhawk]] ''(aka Christian Groessler)''. The Dreamcast version uses the [[KallistiOS]] library, and is based on Subversion repository version 560. It can be found at the SourceForge page here: [http://cadcdev.sourceforge.net/ KOS]. The needed BIOS roms can also be found at SourceForge: [http://prdownloads.sf.net/atari800/xf25.zip BIOS Roms]. ==Downloads== * 0.78 - [ftp://ftp.groessler.org/pub/chris/dreamcast/atari800dc/0.78/atari800dc-0.78-bin.tar.gz Plainfiles] - 08/17/08 * 0.78 - [ftp://ftp.groessler.org/pub/chris/dreamcast/atari800dc/0.78/atari800dc-0.78.tar.gz Source] - 08/17/08 * 0.77 - [http://dcemulation.org/1-newsdump/emulators/atari800dc/atari800dc-0.77-bin.tar Plainfiles] - 09/18/07 * 0.77 - [http://dcemulation.org/1-newsdump/emulators/atari800dc/atari800dc-0.77.tar Source] - 09/18/07 ==Links== * [http://fly.to/ataridc Atari 800 DC Info Site] * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=7566&st=0&sk=t&sd=a DCEmulation Forums] 9022fde5de444f76ab43149323088559d9a36e2a (D)cs2600 0 784 1926 2023-03-01T19:22:56Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=(D)cs2600| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=public beta 13/09/01| downloads=[http://www.dcemulation.com/files/..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=(D)cs2600| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=public beta 13/09/01| downloads=[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600dj.zip DiscJuggler]<br/>[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600nero.zip Nero]<br/>[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600plain.zip Plain Files]<br/>| release date=09/13/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://www.atarihq.com/danb/emulation.shtml#myemulators Virtual VCS]<br/>by Dan Boris| systems=Atari 2600 VCS| NTSCVGAPAL=NTSC| firstversion=[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600plain.zip public beta 13/09/01]<br/>09/13/01| best=No. We recommend<br/>[[Stella DC]]| isactive=No }} (D)cs2600 was one of the first emulators ported to the Sega Dreamcast. It is now discontinued, and [[Stella DC]] is now the better of the two Atari 2600 VCS emulators available. =Known bugs= *Keypad emulation doesn't work right *[d]cs hangs up/reboots when a unsupported game is started *Rom Selection Screen gets messed up after playing a few games =Controls= '''Graphical User Interface - Controls'''<br/> *Press UP/DOWN to choose a menu item and A to activate it. *Press B to leave a menu. '''Rom Selection Screen'''<br/> *Press A to start a game. *Press X to see which Bank Switching Scheme will be used if the Bank Switching *Scheme option is set to "auto". *Press L+R+START to leave a game. *Press Left or Right to move a page forward/backward *Press L or R to move a 5 pages forward/backward '''ATARI2600 Buttons'''<br/> *X - Toggle BW/Color Mode *L - Reset *R - Select *START+A - P0 Pro *START+B - P1 Pro *START+X - P0 Amateur *START+Y - P1 Amateur '''ATARI2600 JOYPAD'''<br/> *A - FIRE *Digital Pad - Move '''ATARI2600 Trackball'''<br/> *A - FIRE *Analogue Stick - Move '''ATARI2600 Keypad'''<br/> (a Dreamcast Keyboard is required to use the ATARI2600 Keypad)<br/> *P0 - Keys: **1,2,3,Q,W,E,A,S,D,Z,X,C *P1 - Keys: **5,6,7,T,Y,U,G,H,J,B,N,M 61167366ab5324cb4f4125c18db1f71cef8385e5 File:Stella.jpg 6 785 1927 2023-03-01T19:24:05Z Unknown user 0 wikitext text/x-wiki Stella 0ab73ab5f1ffe95b96a02d91a5831ebb860ac9ab Stella DC 0 786 1928 2023-03-01T19:24:22Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DCStella| image=[[Image:Stella.jpg|250px]]| homepage=[http://svolli.org/software/dcstella/ Homepage]| version=V0.2F| downloads..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCStella| image=[[Image:Stella.jpg|250px]]| homepage=[http://svolli.org/software/dcstella/ Homepage]| version=V0.2F| downloads=[http://www.dcemulation.org/files/emulators/stelladc/stella02f.zip Plain Files]<br/>| release date=04/25/04| author=[[SvOlli]]| original=Bradford Mott<br/>(Stella Atari 2600 VCS)| systems=Atari 2600 VCS| best=Yes.| isactive=No }} StellaDC is the best Atari 2600 emulator for Dreamcast. It is based on Stella and was ported by German Dreamcast developer [[SvOlli]]. There's sound while emulating games and DCStella runs pretty fast. Unfortunately there are problems with many PAL games. =Controls= '''In the menu:'''<br/> *Up/Down - Highlight a game *Left/Right - Go to next page of games *A - Load game '''During game:'''<br/> *Directional pad or joystick - Move *A - Fire *Y - Toggle Difficulty A/B *B - Toggle Black and White/Color *X - Select game *Start - Reset game *L+R - Exit to menu *B, X, Start, and L+R only work on the first controller [[Category:Emulator]] e6886b51b34bf729850e00de5ffe37fd187fa0eb DC7800 0 787 1929 2023-03-01T19:26:02Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=[http://www.dcemulation.org/files/emulators/a78..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=[http://www.dcemulation.org/files/emulators/a7800new.rar Plain Files] [http://www.dcemulation.org/files/emulators/dc7800.zip Plain Files] v1<br/> [http://www.dcemulation.org/files/sbi3.0/DCA7800v2_CG.sbi SBI] v1 <br/>| release date=Unknown| last update=16/02/04| author=Ian Micheal| original=N/A| systems=Atari 2600 / Atari 7800| best=Unknown| isactive=No }} Developer: Ian Micheal<br> Updated: 16-02-04<br> Version: v3<br> An Atari 2600/7800 emulator. [[Category:Emulator]] 80b8e16a335896c3a4fed34490e37b53346497a5 File:Crabemu.png 6 788 1930 2023-03-01T19:29:09Z Unknown user 0 wikitext text/x-wiki Crabemu 9ae8adb205b2445be87acc96885125e816c4d671 CrabEmu 0 789 1931 2023-03-01T19:29:19Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=CrabEmu| image=[[Image:crabemu.png]]| homepage=[http://crabemu.sourceforge.net Homepage]| version=0.2.0| downloads=[http://sou..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=CrabEmu| image=[[Image:crabemu.png]]| homepage=[http://crabemu.sourceforge.net Homepage]| version=0.2.0| downloads=[http://sourceforge.net/projects/crabemu/files/CrabEmu/0.2.0/CrabEmu-0.2.0-dc.tar.bz2/download Plain Files]<br/>[http://sourceforge.net/projects/crabemu/files/CrabEmu/0.2.0/CrabEmu-0.2.0.tar.bz2/download Source Code]| release date=2/27/2013| author=Lawrence Sebald<br/>([[BlueCrab]])| original=[http://crabemu.sourceforge.net CrabEmu]<br/>by Lawrence Sebald ([[BlueCrab]])| systems=Sega Master System<br />Game Gear<br />SG-1000<br />ColecoVision (SVN r107+ or 0.2.0 and later)<br />NES (SVN r166+ or 0.2.0 and later)<br />CHIP-8 (SVN r249 or later)| best=Maybe?| refreshrate=50/60Hz| isactive=Yes }} CrabEmu is a port of the emulator of the same name originally for Mac OS X. It currently emulates Sega Master System, Game Gear, SG-1000, ColecoVision and the NES. Other consoles are planned for future versions. Development is mainly focused on 8-bit Sega consoles. The code for the other consoles (especially the NES) is not as mature and thus is not nearly as complete. =Controls= '''Rom Selection Screen'''<br/> *Press A to start a game. *Hold Left Trigger and press A to run the game in a stretched full-screen mode. *Up/Down on Directional Pad - move up/down one rom in the menu. *Left/Right on Directional Pad - move up/down a page of roms in the menu. '''SMS/Game Gear/SG-1000 In-Game Buttons'''<br/> *A - Button 1 *B - Button 2 *START - Game Gear Start Button *Directional Pad - Directional Pad *Left Trigger + Y - Return to Rom Select Screen *Right Trigger + Y - Save SRAM to VMU in slot A1. '''ColecoVision In-Game Buttons'''<br /> *Joystick - ColecoVision Joystick *A - Left Action Button *B - Right Action Button *X - Button 1 *Y - Button 2 *DPad Up - Button 3 *DPad Down - Button 4 *DPad Left - Button 5 *DPad Right - Button 6 *Left Trigger + A - Button 7 *Left Trigger + B - Button 8 *Left Trigger + DPad Up - Button 9 *Left Trigger + DPad Down - Button * *Left Trigger + DPad Left - Button 0 *Left Trigger + DPad Right - Button # '''NES In-Game Buttons'''<br/> *A - B *B - A *START - Start *B - Select *Directional Pad - Directional Pad 57c09ec360b182b18273132fa83cb991fe581d33 File:Dcolem4.jpg 6 790 1932 2023-03-01T19:31:10Z Unknown user 0 wikitext text/x-wiki [D]Colem 3468e9e68bc2542e40aaf4738fef86e1f61705c1 (D)Colem 0 791 1933 2023-03-01T19:31:15Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=[D]Colem| image=[[Image:Dcolem4.jpg|center|250px]]| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=0.99| downloads=[http://..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=[D]Colem| image=[[Image:Dcolem4.jpg|center|250px]]| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=0.99| downloads=[http://www.dcemulation.com/files/emulators/d99sb.zip DiscJuggler]<br/>[http://www.dcemulation.com/files/emulators/d99p.zip Plain Files]| release date=06/18/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://fms.komkon.org/ColEm/ ColEm]<br/>by Marat Fayzullin| systems=ColecoVision| firstversion=[http://www.dcemulation.com/files/emulators/dcolem/dcolemwhatever.zip FIXME]<br/>| best=Yes| isactive=No| refreshrate=50Hz }} [D]Colem is the only ColecoVision emulator on the Sega Dreamcast. It is based on [http://fms.komkon.org/ColEm/ ColEm] was ported to Dreamcast by Austrian Dreamcast developer [[Gonzo]]. [D]Colem is reported to run fullscreen with sound. =Known bugs= *8 and 9 keys aren't properly emulated *Video flickering on 60Hz displays [[Category:Emulator]] 1bff97e33f342474094596bf2d6303a17de9cd8c 1934 1933 2023-03-01T19:34:35Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=[D]Colem| image=[[File:Dcolem4.jpg|center|250px]]| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=0.99| downloads=[http://www.dcemulation.com/files/emulators/d99sb.zip DiscJuggler]<br/>[http://www.dcemulation.com/files/emulators/d99p.zip Plain Files]| release date=06/18/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://fms.komkon.org/ColEm/ ColEm]<br/>by Marat Fayzullin| systems=ColecoVision| firstversion=[http://www.dcemulation.com/files/emulators/dcolem/dcolemwhatever.zip FIXME]<br/>| best=Yes| isactive=No| refreshrate=50Hz }} [D]Colem is the only ColecoVision emulator on the Sega Dreamcast. It is based on [http://fms.komkon.org/ColEm/ ColEm] was ported to Dreamcast by Austrian Dreamcast developer [[Gonzo]]. [D]Colem is reported to run fullscreen with sound. =Known bugs= *8 and 9 keys aren't properly emulated *Video flickering on 60Hz displays [[Category:Emulator]] 53925102d0882f699dff2a5d8faa2cafe9772351 Odd-DC 0 792 1935 2023-03-01T19:35:21Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=OddDC| image=no image| homepage=[http://dcolem.emuunlim.com Homepage]| version=Early Beta| downloads=[http://www.dcemulation.org/file..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=OddDC| image=no image| homepage=[http://dcolem.emuunlim.com Homepage]| version=Early Beta| downloads=[http://www.dcemulation.org/files/emulators/oddDC.zip Plain Files]| release date=09/03/01| author=[[Gonzo]]| original=O2EM| systems=Odyssey2 (G7000 in Europe)| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} oddDC is a port of O2EM 0.65, an Odyssey2 (G7000 in Europe) emulator written by Dan Boris(dboris@erols.com). To learn more about the emulator itself check /docs/o2em.txt. Latest Status: * 2 player support =Downloads= [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/oddDCDJ.zip Disk Juggler]<br> [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/oddDC.zip Plain Files]<br> =Burning Info ( Check Readme File First!! )= [http://www.dcemulation.org/newhelp/dj3burn.php?item=Odd-DC&filename=oddDCDJ.zip&imagefile=oddDC.cdi Odd-DC Disc Juggler Burning Tutorial]<br> [http://www.dcemulation.org/newhelp/romdisknodirnero.php?item=Odd-DC Odd-DC Rom Disk Burning Tutorial]<br> [http://www.dcemulation.org/newhelp/selfboot.php?item=Odd-DC&binfile=1st_read.bin Odd-DC Self Boot Plain Files Tutorial]<br> [[category:Emulator]] ed7472310f7252e504cd3dffcd0ac2a20c917873 IntelliMESS 0 793 1936 2023-03-01T19:36:03Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=IntelliMESS| image=No Screenshot available| homepage=Unknown| version=V2| downloads= [http://www.dcemulation.org/files/emulato..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=IntelliMESS| image=No Screenshot available| homepage=Unknown| version=V2| downloads= [http://www.dcemulation.org/files/emulators/intvdc2.rar Plain Files (v2)] [http://www.dcemulation.org/files/emulators/intvdc2.zip Plain Files] [http://www.dcemulation.org/files/sbi3.0/InTVDC2_CG.sbi Selfboot Inducer] <br/>| release date=Unknown| last update=Unknown| author=Ian Micheal| original=ice88's M.E.S.S.| systems=Intellivision| best=Unknown| isactive=Unknown }} Developer: Ian Micheal Updated: 2003 An Intellivision emulator based on ice88's M.E.S.S. port. It doesn't have full controller support but does run some games that don't require 16 buttons to play. [http://www.dcemulation.org/files/readme/intv.txt Intellivision M.E.S.S. Final Readme] [[Category:Emulator]] 387fb2282b1c78a71d6a4dc1424ee65f9aa7b011 Vectrex MESS 0 794 1937 2023-03-01T19:36:33Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Vectrex MESS| image=No Screenshot available| homepage=Unknown| version=Unknown| downloads=[http://www.dcemulation.org/files/em..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Vectrex MESS| image=No Screenshot available| homepage=Unknown| version=Unknown| downloads=[http://www.dcemulation.org/files/emulators/Vectrex.zip Plain Files] [http://www.dcemulation.org/files/emulators/VectrexCDI.rar Discjuggler (newer?)] [http://www.dcemulation.org/files/emulators/VectrexCDI.zip Discjuggler] [http://www.dcemulation.org/files/sbi3.0/DCVectrex_072_CG.sbi Selfboot Inducer] <br/>| release date=Unknown| author=Ian Micheal| original=ice88's M.E.S.S| systems=Vectrex| best=Unknown| isactive=Unknown }} Developer: Ian Micheal Updated: 2003 A Vectrex emulator based on ice88's M.E.S.S port. It is not compatible with light pen & 3D imager games. [[category:emulator]] 9ba167eb3a6f755db07b68992b9ba8c59db3492d File:Pcecast.jpg 6 795 1938 2023-03-01T19:37:31Z Unknown user 0 wikitext text/x-wiki PCECast 120412e338b08c46f45f1c0140568304af14a072 PCECast 0 796 1939 2023-03-01T19:37:36Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=PCEcast| image=[[Image:Pcecast.jpg]]| homepage=Unknown| version=Unknown| downloads=[http://dcemulation.org/1-newsdump/emulator..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=PCEcast| image=[[Image:Pcecast.jpg]]| homepage=Unknown| version=Unknown| downloads=[http://dcemulation.org/1-newsdump/emulators/pcecast/pcecast.zip Plain Files] - 06/01/07<br/>| release date=Unknown| author=[[LTK]]| original=N/A| systems=PC Engine / TurboGrfx16| best=Unknown| isactive=Unknown }} PCECast is a PC Engine / TurboGrfx16 emulator for Dreamcast by [[LTK]] a.k.a Uguru. LTK is known for Dreamcast projects like [[HOTA]], [[MSXCast]], [[CPCast]] and others. ==Features== * Almost full speed * Games in PCE, ISO, HCD, TOC, NEC format supported * CD-ROM Games are suported as ISO+WAV (HCD, TOC, NEC) * Sound & CD Sound * .pce ROMs can be zipped * Analog stick support * Savestate with mini-screenshot * 6 button pad support * FPS counter ==Instructions== You can add your ROMs anywhere on the disc: Put .pce ROMs e.g. in /PCE/ folder, .iso files in /ISO/. Be sure to have syscard.pce in root! ==Downloads== * PCECast WIP - <s>[http://www.dchelp.net/sbi/files/Emus/PCECast_WIP_06012007.sbi SBI]</s> - 06/01/07 (Use with [[SBInducer]]) [[Category:Emulator]] 3775fb19bd677b384ed1a0e7be8cd5bc09551378 1940 1939 2023-03-01T19:37:50Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=PCEcast| image=[[File:Pcecast.jpg]]| homepage=Unknown| version=Unknown| downloads=[http://dcemulation.org/1-newsdump/emulators/pcecast/pcecast.zip Plain Files] - 06/01/07<br/>| release date=Unknown| author=[[LTK]]| original=N/A| systems=PC Engine / TurboGrfx16| best=Unknown| isactive=Unknown }} PCECast is a PC Engine / TurboGrfx16 emulator for Dreamcast by [[LTK]] a.k.a Uguru. LTK is known for Dreamcast projects like [[HOTA]], [[MSXCast]], [[CPCast]] and others. ==Features== * Almost full speed * Games in PCE, ISO, HCD, TOC, NEC format supported * CD-ROM Games are suported as ISO+WAV (HCD, TOC, NEC) * Sound & CD Sound * .pce ROMs can be zipped * Analog stick support * Savestate with mini-screenshot * 6 button pad support * FPS counter ==Instructions== You can add your ROMs anywhere on the disc: Put .pce ROMs e.g. in /PCE/ folder, .iso files in /ISO/. Be sure to have syscard.pce in root! ==Downloads== * PCECast WIP - <s>[http://www.dchelp.net/sbi/files/Emus/PCECast_WIP_06012007.sbi SBI]</s> - 06/01/07 (Use with [[SBInducer]]) [[Category:Emulator]] ec1fb11d2385936280eb9ae2276b0b05aa22e017 Dream Engine 0 797 1941 2023-03-01T19:38:39Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DreamEngine| image=| homepage=[http://www.billnagel.com/ Homepage]| version=V0.01| downloads=NOTE: DOWNLOADS AND SCREENSHOTS..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamEngine| image=| homepage=[http://www.billnagel.com/ Homepage]| version=V0.01| downloads=NOTE: DOWNLOADS AND SCREENSHOTS WERE POINTING TO DEAD DCHOMEBREW<br/>| release date=Unknown| last update=07-28-02| author=Bill Nagel| original=N/A| systems=TG-16/Pc Engine emulator| best=Unknown| isactive=Unknown }}Developer: [http://www.billnagel.com/ Bill Nagel] Updated: 07-28-02 Version 0.01 A TG-16/Pc Engine emulator!! Speed varies but many games run at (or near) full speed. Currently no sound. Speed: 80% Sound: None [http://www.dcemulation.org/files/readme/DreamEngine0.01.txt Dream Engine 0.01 README file] [[Category:Emulator]] ff4a43846969cffb5a543855ffa35a7b0f77a7e4 HuCast 0 798 1942 2023-03-01T19:39:14Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | HuCast |- border="0" cellpadding="2" cellspacing="1" al..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | HuCast |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://screamcast.net/ Homepage]<br />''(Defunct Domain)''}}} |- style="background:#ffffff" |Latest Version || {{{version|Preview}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://web.archive.org/web/20080528233707/http://www.screamcast.net/publicdownloads/HuCast_Preview.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|02/28/2005}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://www.zeograd.com/ Hugo] 2.11}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|PC Engine/<br />TurboGrafx-16}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|No}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50/60Hz}}} |} ==History== '''''Per Readme:<br /> '' 'A really hacked up port of Hugo 2.11 preview to the DC by Quzar. ''This can read two different kinds of files, *.pce and *.iso (where the iso is an image of the data track of a Super CD game.) ''As far as I know, It supports all possible resolutions (not tested). ''Roms should be put in the root of the CD with the emulator on it. ''To play CD games you need to also have a matching System card rom that may be named any of the following things: "syscard.pce","syscard3.pce","syscard30.pce" ''Every game that I have tested runs about the same speed if not faster than in DreamEngine, but has sound.' ===Controls=== * Start → Sound On/off (this does not affect speed in any way) * A → I * B → II * X → Run * Y → Select ==Downloads== * Hucast Preview - [http://dreamcast.dcemu.co.uk/HuCast_Preview.zip Plainfiles] - 02/28/2005 8e0ab09dc15f5d0a6e7e08f2280dae5c47d4b2e9 DCNin64 0 799 1943 2023-03-01T19:40:55Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DCNin 64| image=[[File:dcnin64.jpg|center|250px]]| homepage=[http://gpf.dcemu.co.uk/dcnin64.shtml Homepage]| version=Alpha| downloads..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCNin 64| image=[[File:dcnin64.jpg|center|250px]]| homepage=[http://gpf.dcemu.co.uk/dcnin64.shtml Homepage]| version=Alpha| downloads=[http://gpf.dcemu.co.uk/files/dcnin64.zip Plain Files]| release date=?| author=[[GPF]]| original=Nincest 64| systems=Nintendo 64| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} ==DCNin64== DCNin64 was the first Nintendo 64 emulator for the Dreamcast. It is based on Niincet 64 and was ported by [[GPF]]. a9de96e9940081b31eb6037365351dfdc04ba2a5 File:Daedalusdc.png 6 800 1944 2023-03-01T19:44:02Z Unknown user 0 wikitext text/x-wiki Daedalus DC 7d11d44898c97fb3b41b1155cfeabf9cbc1d5a83 DaedalusDC 0 801 1945 2023-03-01T19:44:13Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Daedalus| image=[[File:daedalusdc.png|center|250px]]| homepage=[http://www.maturion.de/daedalus Homepage]| version=R8| downloads=[htt..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Daedalus| image=[[File:daedalusdc.png|center|250px]]| homepage=[http://www.maturion.de/daedalus Homepage]| version=R8| downloads=[http://www.maturion.de/dreamcast/DaedalusDC.rar Plain Files]| release date=01/06/2008| author=[[Simpson474]]| original=Daedalus<br/>([[StrmnNrmn]])| systems=Nintendo 64| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Daedalus is a Nintendo 64 emulator by [[StrmnNrmn]]. The project was started in 1998 and the first release was in 2000. In early 2001 Daedalus got hosted by the popular Dreamcast website [http://www.boob.co.uk B00B! Dreamcast Research]. During the same time, other developers became involved in the development of Daedalus, most notably [[CyRUS64]] who is a well known face in the Dreamcast scene. StrmnNrmn also ported Daedalus to the Xbox but after his port got leaked he decided not to release it. When [[CyRUS64]] somehow left the Dreamcast and console scene in general (around june 2003) [[StrmnNrmn]] stopped development of his emulator. In early 2006 StrmnNrmn picked up Daedalus again and ported it to the Sony PSP. Until late 2007 StrmnNrmn was actively developing the PSP port of Daedalus but then he announced he'd stopped work on DaedalusPSP and he stated that he'd port Daedalus to an "unkown" platform. In late 2007 a German Dreamcast developer named [[Simpson474]] ported Daedalus to the Dreamcast and released it in January 2008. The Dreamcast version currently runs with about 10 fps in Super Mario 64. DaedalusDC consists of two port of Daedalus. The one is based on the PC version of Daedalus (from 2001), the other one is based on the PSP port (from 2006-2007). While the one based on the PC version offers higher compatibility, the one based on the PSP port can be considered faster. There are several YouTube videos showing DaedalusDC running on real hardware. Although, it is extremly slow, the Dreamcast port of Daedalus is reported to be compatible with a number of several popular games, including Mario Kart 64, Super Mario 64 and Zelda - Ocarina of Time. The Dreamcast version can be downloaded from [http://www.rapidshare.com/files/81713061/DaedalusDC.rar.html Rapidshare] or [http://www.maturion.de/dreamcast/DaedalusDC.rar Maturion.de]. Below is the video [[Simpson474]] published on YouTube: *http://www.youtube.com/watch?v=1eEUmZtRFME Other videos showing DaedalusDC in action: *[http://www.youtube.com/watch?v=-Lgy05-bi1c DaedalusDC running Mario Kart] *[http://www.youtube.com/watch?v=jm3k9pXzWAk DaedalusDC running Zelda -Ocarina of Time] ==Links== *[http://strmnnrmn.blogspot.com StrmnNrmn's Blog] *[http://daedalus.boob.co.uk| Old Daedalus site @ B00B] *[http://www.maturion.de/daedalus Daedalus site (restored) @ Maturion.de] [[Category:Emulator]] 7e0d1988ffb763031f6c498be6950be750a9e42e Simpson474 0 802 1946 2023-03-01T19:44:30Z Unknown user 0 Created page with "==Simpson474== Simpson474 was a German Dreamcast programmer. He has never been active in the well known Dreamcast forums but in December 2007 he released a video of his port..." wikitext text/x-wiki ==Simpson474== Simpson474 was a German Dreamcast programmer. He has never been active in the well known Dreamcast forums but in December 2007 he released a video of his port of [[DaedalusDC|Daedalus]] for the Dreamcast. In January 2008 he decided to release both source and binary of his port. 90598433b43ee38b03b683a85c26d62df5bcc873 StrmnNrmn 0 803 1947 2023-03-01T19:45:25Z Unknown user 0 Created page with "==StrmnNrmn== StrmnNrmn (Stormin' Normin) is well known face in the PSP scene. He developed [[DaedalusDC|Daedalus]], a Nintendo 64 emulator that was originally created for th..." wikitext text/x-wiki ==StrmnNrmn== StrmnNrmn (Stormin' Normin) is well known face in the PSP scene. He developed [[DaedalusDC|Daedalus]], a Nintendo 64 emulator that was originally created for the PC and got a lot of help from [[CyRUS64]]. Later Daedalus got ported to the Xbox. In late 2003 he retired from Daedalus. In 2006 he returned to the scene and ported Daedalus to the PSP. In early 2008 [[Simpson474]] finally ported Daedalus to the Dreamcast. *[http://strmnnrmn.blogspot.com/ StrmnNrmn's Blog] *[http://www.maturion.de/daedalus Daedalus homepage (restored)] *[http://daedalus.boob.co.uk Daedalus homepage (original)] 63e4f07ff58a7f2119d766d9dd6004ed931a7864 File:Nesterdcsescreen.png 6 804 1948 2023-03-01T19:47:41Z Unknown user 0 wikitext text/x-wiki NesterDC SE a7a8321ed1bd90589a187204939c87a9650ec790 File:Nesterdcse.gif 6 805 1949 2023-03-01T19:48:29Z Unknown user 0 wikitext text/x-wiki NesterDC SE Logo a6128e247010149cb9f6a342824a85473d64dc1b NesterDC SE 0 806 1950 2023-03-01T19:48:40Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=NesterDC SE| image=[[File:nesterdcse.gif]]<br />[[File:nesterdcsescreen.png|center|250px]]| homepage=[http://www.sch3rz0.com/nesterdcse..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC SE| image=[[File:nesterdcse.gif]]<br />[[File:nesterdcsescreen.png|center|250px]]| homepage=[http://www.sch3rz0.com/nesterdcse/ Homepage]| version=1.1 (Unofficial)| downloads=[http://dcemulation.org/files/emulators/NesterSEv11_plain_files.rar Plain Files]<br>[http://dcemulation.org/files/emulators/NesterSEv11_cdi.rar DiscJuggler] (w\ Homebrew)| release date=December 9, 2008| author=[[Scherzo]]; 1.1 by<br>[[Christuserloeser]]| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester]| systems=NES, Famicom| best=Yes| refreshrate=50Hz/60Hz| isactive=No }} NesterDC SE is an highly polish and updated version of NesterDC 7.1, an already splendid NES emulator, under development by Scherzo. In late 2008 (December) [[Christuserloeser]] released an "Unofficial" update to NesterDC SE that makes changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. These changes were done via JavaScript so if the source code is what you are looking for grab 1.0's source below. Official DCEmulation Forum Threads:<br> [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=74417 NesterDC SE 1.0]<br> [http://dcemulation.org/phpBB/viewtopic.php?f=72&t=98192 NesterDC SE 1.1 (Unofficial Build)] '''Features: *Greatly Improved Compatibility (VS ROMs correctly supported) *An NSF player *Controller buttons can be remapped *Stereo separation of each NES sound channel *Full screen stretched and pixel-for-pixel video modes *Game-Genie implementation *Multiple save state slots (with the first slot being backwards compatible) *Supports Zipped ROMs *CD Builder grabs Manual & Cartridge, Game-Genie and more from master list *Various game related images by which you can use to browse the ROM library *Favorite Game list *Ability to enter your own personal notes about a game and save these notes on your VMU ==Older Versions== *1.0 [http://dcemulation.org/files/emulators/nesterdcse/NesterDCSE_2005-12-10.zip Plain Files] - 12/9/05 *1.0 [http://dcemulation.org/files/emulators/nesterdcse/NesterDCSE-src_2005-12-24.zip Source] - 12/24/05 *1.0 [http://dcemulation.org/files/emulators/nesterdcse/NesterDCSE-KOS-src_2005-12-24.zip KOS Source] - 12/24/05 ==Master Library== If using the NesterDC SE ''CD Builder'' for version 1.0, replace the default URL with one of the following mirrors. *Local - http://nesterdcse.dcemulation.org/master_library/ *External - http://dcevolution.net/nesterdcse/master_library/ [[Category:Emulator]] 8f36bb99aa87d7da3fec628e26b3a121c79a9548 1951 1950 2023-03-01T19:48:59Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC SE| image=[[Image:nesterdcse.gif]]<br />[[File:nesterdcsescreen.png|center|250px]]| homepage=[http://www.sch3rz0.com/nesterdcse/ Homepage]| version=1.1 (Unofficial)| downloads=[http://dcemulation.org/files/emulators/NesterSEv11_plain_files.rar Plain Files]<br>[http://dcemulation.org/files/emulators/NesterSEv11_cdi.rar DiscJuggler] (w\ Homebrew)| release date=December 9, 2008| author=[[Scherzo]]; 1.1 by<br>[[Christuserloeser]]| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester]| systems=NES, Famicom| best=Yes| refreshrate=50Hz/60Hz| isactive=No }} NesterDC SE is an highly polish and updated version of NesterDC 7.1, an already splendid NES emulator, under development by Scherzo. In late 2008 (December) [[Christuserloeser]] released an "Unofficial" update to NesterDC SE that makes changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. These changes were done via JavaScript so if the source code is what you are looking for grab 1.0's source below. Official DCEmulation Forum Threads:<br> [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=74417 NesterDC SE 1.0]<br> [http://dcemulation.org/phpBB/viewtopic.php?f=72&t=98192 NesterDC SE 1.1 (Unofficial Build)] '''Features: *Greatly Improved Compatibility (VS ROMs correctly supported) *An NSF player *Controller buttons can be remapped *Stereo separation of each NES sound channel *Full screen stretched and pixel-for-pixel video modes *Game-Genie implementation *Multiple save state slots (with the first slot being backwards compatible) *Supports Zipped ROMs *CD Builder grabs Manual & Cartridge, Game-Genie and more from master list *Various game related images by which you can use to browse the ROM library *Favorite Game list *Ability to enter your own personal notes about a game and save these notes on your VMU ==Older Versions== *1.0 [http://dcemulation.org/files/emulators/nesterdcse/NesterDCSE_2005-12-10.zip Plain Files] - 12/9/05 *1.0 [http://dcemulation.org/files/emulators/nesterdcse/NesterDCSE-src_2005-12-24.zip Source] - 12/24/05 *1.0 [http://dcemulation.org/files/emulators/nesterdcse/NesterDCSE-KOS-src_2005-12-24.zip KOS Source] - 12/24/05 ==Master Library== If using the NesterDC SE ''CD Builder'' for version 1.0, replace the default URL with one of the following mirrors. *Local - http://nesterdcse.dcemulation.org/master_library/ *External - http://dcevolution.net/nesterdcse/master_library/ [[Category:Emulator]] bdb45890205a9d27eac8e809ff48ad644bc0d482 File:Nester3-4.jpg 6 807 1952 2023-03-01T19:50:03Z Unknown user 0 wikitext text/x-wiki NesterDC 34cbe7215238735d6a3bc8f3a50300cece0cd6f8 NesterDC 0 808 1953 2023-03-01T19:50:08Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=[http://dcemulation.org/files/emulators/nesterdc-7.1.zip Plain Files]<br/>[http://www.dcemulation.org/files/emulators/nesterdc-7.1pb.zip Plain Files] 7.1+| release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Older Versions== * 7.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-7.0.zip Plain Files] * 7.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-7.0.tar.gz Source Code] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/NesterDC.exe Best Damned Tutorial] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.zip Plain Files] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.tar.gz Source Code] * 5.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-5.0.tar.gz Source Code] - 12/03/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_src.zip Source Code] - 6/03/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1.zip Plain Files] - 2/20/01 4a51dd10d3af35cdfe6c8434e439af01d571b5a0 Ken Friece 0 809 1954 2023-03-01T19:50:31Z Unknown user 0 Created page with "Ken Friece was a Dreamcast developer. He started developing [[NesterDC]] together with [[Takayama Fumihiko]]. When version 3.0 of NesterDC was released, Takayama took over the..." wikitext text/x-wiki Ken Friece was a Dreamcast developer. He started developing [[NesterDC]] together with [[Takayama Fumihiko]]. When version 3.0 of NesterDC was released, Takayama took over the project and Ken retired from the project. ==Links== *[http://nesterdc.emulation64.com Ken's NesterDC-Website] f45188dab8f4a03cfd98c5e8061615d382e940c7 Takayama Fumihiko 0 810 1955 2023-03-01T19:50:57Z Unknown user 0 Created page with "Takayama Fumihiko was a Japanese [[Dreamcast]] developer. He ported Nester and GNUBoy to the Dreamcast([[NesterDC]] and [[DCGNUboy]] respectively). His Dreamcast-site can be..." wikitext text/x-wiki Takayama Fumihiko was a Japanese [[Dreamcast]] developer. He ported Nester and GNUBoy to the Dreamcast([[NesterDC]] and [[DCGNUboy]] respectively). His Dreamcast-site can be found at [http://www.pqrs.org/~tekezo/dreamcast/index.html.en http://www.pqrs.org/~tekezo/dreamcast/index.html.en]. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=8822 Takayama Fumihiko's Profile on DCEmulation.org] 47d9f06a86cb1d29cadf485437c9fcc728f3300b Warmtoe 0 811 1956 2023-03-01T19:51:42Z Unknown user 0 Created page with "Warmtoe released several Dreamcast programs. On September 18, 2002, he created a driver for Dreamcast lightgun support in [[KallistiOS]]. On October 03, 2002, he released a..." wikitext text/x-wiki Warmtoe released several Dreamcast programs. On September 18, 2002, he created a driver for Dreamcast lightgun support in [[KallistiOS]]. On October 03, 2002, he released a version of MAME that included Dreamcast lightgun support titled [[MAIM]]. On October 21, 2002, he released [[MDCNG]], a Neo Geo emulator based on MAIM. On March 7, 2003, he released NesterDC 7.1+, an updated version of the NES emulator [[NesterDC]], that included Dreamcast lightgun support. On January 22, 2004, he released [[Trigger Happy]], a lightgun game and [[Burger DC]], a Burger Time clone for Dreamcast. On July 22nd, 2006, he released an updated version of [[Genesis Plus]] with the prefix GWPT. 557e1db472e44215b8566599dcb757fe5d5428a7 Scherzo 0 812 1957 2023-03-01T19:52:16Z Unknown user 0 Created page with "Scherzo was a Dreamcast prorgammer. He released [[Super Famicast]] and [[NesterDC SE]]. We have also [[Interviews:Scherzo|interviewed]] him. *[http://dcemulation.org/phpBB/me..." wikitext text/x-wiki Scherzo was a Dreamcast prorgammer. He released [[Super Famicast]] and [[NesterDC SE]]. We have also [[Interviews:Scherzo|interviewed]] him. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=14018 Scherzo's profile on DCEmulation forums] *[http://www.sch3rz0.com Scherzo's Site] b0fe04221a63b44492ffb019e90ec2a90dfad3ea File:Frnes1.jpg 6 813 1958 2023-03-01T19:54:07Z Unknown user 0 wikitext text/x-wiki Frnes1 e6fedb166fa991f9c866e905191268694dd17634 File:Frnes2.jpg 6 814 1959 2023-03-01T19:54:14Z Unknown user 0 wikitext text/x-wiki Frnes2 666bd545f9ff08388de2becaf7ae55d8788ed427 File:Frnes3.jpg 6 815 1960 2023-03-01T19:54:21Z Unknown user 0 wikitext text/x-wiki Frnes3 86db4cbf31a39014477de68c747cb4eb6674654a File:Frnes4.jpg 6 816 1961 2023-03-01T19:54:27Z Unknown user 0 wikitext text/x-wiki Frnes4 6ed28837f603fe419a300604465779ed5017155b FrNES 0 817 1962 2023-03-01T19:54:36Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=[http://dcemulation.com/files/emulators/Fr..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=[http://dcemulation.com/files/emulators/FrNES-0.60Final-DJImage.zip DiscJuggler]<br />[http://dcemulation.org/files/emulators/FrNES-0.60Final-NeroImage.zip Nero]<br /> [http://dcemulation.org/files/emulators/FrNES-0.60Final-RawFiles.zip Plain Files]| release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} == About == FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements == Older versions == *[http://dcemulation.org/files/emulators/FrNES-0.60b2-RawFiles.zip 0.60-b2 Plain Files] *[http://dcemulation.org/files/emulators/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[http://dcemulation.org/files/emulators/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[http://dcemulation.org/files/emulators/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[http://dcemulation.org/files/emulators/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] =Screen Shots= [[Image:Frnes1.jpg|center|250px]] [[Image:Frnes2.jpg|center|250px]] [[Image:Frnes3.jpg|center|250px]] [[Image:Frnes4.jpg|center|250px]] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] 42d1b59c76c68ec481aa9e1d57626bf3fbcc917b TuxNES-DC 0 818 1963 2023-03-01T19:56:02Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=TuxNES-DC| homepage=[http://3e8.org/ Homepage]| version=0.2| downloads=[http://dcemulation.org/1-newsdump/emulators/nes/tuxnes-d..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=TuxNES-DC| homepage=[http://3e8.org/ Homepage]| version=0.2| downloads=[http://dcemulation.org/1-newsdump/emulators/nes/tuxnes-dc-0.2-bin.tgz Plain Files]<br>[http://dcemulation.org/1-newsdump/emulators/nes/tuxnes-dc-0.2.tgz Source Code]| release date=2/27/02| author=[[Jim Ursetto]]| original=[http://tuxnes.sourceforge.net/ TuxNES] by<br/>Mike Melanson| systems=NES| best=No.| isactive=No. }} A working NES emulator; working, in the sense that it plays most nes games at 30fps with sound or 50-60fps without. And the source code has been made public. Status: Emulation aspect: Almost all games work at 30FPS with sound. In fact, the renderer is artificially locked to 30FPS (frameskip = 1). Without sound, I benchmarked between 50-60 FPS on most games. You can disable sound, vsync and frameskip to achieve these speeds. Sound works well, but is subject to some artifacts. If game speed drops below 30FPS, sound will break up. Save games are implemented, but you need dcload and a PC to take advantage. I.e., vmu saving is not supported. Full sourcecode released. =Older Versions= * [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/tuxnes-dc-0.1-bin.zip 0.1 Plain Files] - 12/14/01 affe9e6f637c2c98760e4f5a7dc8d12b6e82c78c File:Gleam.jpg 6 819 1964 2023-03-01T19:56:37Z Unknown user 0 wikitext text/x-wiki Gleam! ae241e579057407a22a385dfe03a06832c7269c0 Gleam! 0 820 1965 2023-03-01T19:56:45Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=gleam!| image=[[Image:Gleam.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/gleam/ Homepage]| version=103000| downloads..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=gleam!| image=[[Image:Gleam.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/gleam/ Homepage]| version=103000| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/gleamcdi.zip Disc Juggler ]| release date=01/06/2000| author=[[Chuck Mason]]| original=Many<br/>| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No. }} '''gleam!''' was the first emulator ever to be released for the Dreamcast. It was created by [[Chuck Mason]]. It isn't based on anything, it was made from scratch and has 3 different CPU cores. gleam! is a working NES emulator; working, in the sense that it is compatible with most games. However, it's been discontinued. Although its source code has been made public, the project has never been picked up again by any other developer. Today, emulators such as [[NesterDC]] and [[NesterDC SE]] have by far surpassed gleam! in terms of speed and compatibility and should therefore be used. ==Features== * asm cpu core * More compatibility (mappers 4, 7, etc. are partially supported). * Minor graphics fixes. * 2 Player support! * Now supports sound * Fully interactive setup * Option menu with frame skip * FULL SCREEN option. * Save and Load Support. *[http://www.dcemulation.org/files/emulators/gleamcdi.zip Disc Juggler ] *[http://www.dcemulation.org/files/emulators/gleamnrg.zip Nero] *[http://www.dcemulation.org/files/emulators/gleamez.zip Easy CD] [[Category:Emulator]] c6c6efb9c76d0ca925a4119d65b8a0faa0ee9c00 1966 1965 2023-03-01T19:56:51Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=gleam!| image=[[File:Gleam.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/gleam/ Homepage]| version=103000| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/gleamcdi.zip Disc Juggler ]| release date=01/06/2000| author=[[Chuck Mason]]| original=Many<br/>| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No. }} '''gleam!''' was the first emulator ever to be released for the Dreamcast. It was created by [[Chuck Mason]]. It isn't based on anything, it was made from scratch and has 3 different CPU cores. gleam! is a working NES emulator; working, in the sense that it is compatible with most games. However, it's been discontinued. Although its source code has been made public, the project has never been picked up again by any other developer. Today, emulators such as [[NesterDC]] and [[NesterDC SE]] have by far surpassed gleam! in terms of speed and compatibility and should therefore be used. ==Features== * asm cpu core * More compatibility (mappers 4, 7, etc. are partially supported). * Minor graphics fixes. * 2 Player support! * Now supports sound * Fully interactive setup * Option menu with frame skip * FULL SCREEN option. * Save and Load Support. *[http://www.dcemulation.org/files/emulators/gleamcdi.zip Disc Juggler ] *[http://www.dcemulation.org/files/emulators/gleamnrg.zip Nero] *[http://www.dcemulation.org/files/emulators/gleamez.zip Easy CD] [[Category:Emulator]] 919e68abbdb7072818f52771dc1878e3c5049eaa DarcDC 0 821 1967 2023-03-01T19:57:43Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DarcDC| image=No screenshot available| homepage=Unknown| version=Beta 1| downloads=[http://www.dcemulation.org/dl/dl.php3?url=..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DarcDC| image=No screenshot available| homepage=Unknown| version=Beta 1| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/DarcDC.zip Plain Files]<br/>| release date=Unknown| author=ss_teven| original=Many| systems=PC-Engine/TurboGrafx-16, NES, Sega Master System, Sega SG-1000/3000 & Sega GameGear| best=No| isactive=No }} Developer: ss_teven Version: Beta 1 Last Updated: December 21, 2001 A port of DarcNES, an emulator that will allow you to play PC-Engine/TurboGrafx-16, NES, Sega Master System, Sega SG-1000/3000 & Sega GameGear games. [[category:emulator]] 155197f3bcd7860f0013c3a793bb2b2b6b5dcc40 FCE Ultra DC 0 822 1968 2023-03-01T19:58:16Z Unknown user 0 Created page with "==History== [[Takayama Fumihiko]] the author of the 'unofficial' NesterDC, NesterDC expanded, and the later official versions of NesterDC began porting FCE Ultra (another NES..." wikitext text/x-wiki ==History== [[Takayama Fumihiko]] the author of the 'unofficial' NesterDC, NesterDC expanded, and the later official versions of NesterDC began porting FCE Ultra (another NES emulator) to the Dreamcast sometime in 2001. He stated originally that the APU engine of FCE Ultra was too heavy for the Dreamcast, and was in the process of developing his own. In the end all that was ever released was the [http://en.wikipedia.org/wiki/Source_code source code], which was claimed to have been close to the speed of the then current NesterDC. Unfortunately, that [http://en.wikipedia.org/wiki/Source_code source code] has been lost to the defunct internet pages of the past, and has never been recovered. ===Archives=== Below is the original post from Takayama's [http://web.archive.org/web/20011222191154/http://nemesis.kaz.ac/~fumihit/nesterdc/ archived site]:<br /> '' "2001/11/04 00:51 (JST) ''for developers * ''[http://web.archive.org/web/20011222191154/http://nemesis.kaz.ac/~fumihit/fceu/fceu-0.1.tar.gz fceu-0.1.tar.gz] (553KB, source code only) ''This is FCE Ultra port to Dreamcast. It's too primary stage, but the speed is equal or upper than NesterDC. (And it's code written by C. It's very handy). We'll feedback experience of FCE Ultra porting to NesterDC. ''Original FCE Ultra APU engine is too heavy for Dreamcast, so we must develop APU engine for FCE Ultra. But I cannot touch this code now because I'm in release engineering for NesterDC-4release. Would you write code? ''It's build process is same as NesterDC, and it has same develop environment." a38456f283fd23f6862ce55f3152caa36d8ca188 File:Smashpk ech.jpg 6 823 1969 2023-03-01T20:02:20Z Unknown user 0 wikitext text/x-wiki Smash Pack ROM Loader, Echelon 5c7988a1a575e74c8056a35e4707816557324656 File:Smashpk obs.jpg 6 824 1970 2023-03-01T20:02:34Z Unknown user 0 wikitext text/x-wiki Smash Pack ROM Loader, Obsidian/Lemec 3ee3a5e9eb435a643ecf36c012c736bf7847d334 File:SegaSmPkVol1Front.jpg 6 825 1971 2023-03-01T20:02:46Z Unknown user 0 wikitext text/x-wiki Sega Smash Pack Volume 1 1ca17b65e7c0a5d843bd62430be9ad4f47ce86b5 Sega Smash Pack Volume 1 0 826 1972 2023-03-01T20:02:52Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Sega Smash Pack| image=[[Image:SegaSmPkVol1Front.jpg|center|250px]]| homepage=''none''| version=''n/a''| downloads=''n/a''<br/>| rel..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Sega Smash Pack| image=[[Image:SegaSmPkVol1Front.jpg|center|250px]]| homepage=''none''| version=''n/a''| downloads=''n/a''<br/>| release date=01/31/01| author=Sega<br/>| original=Sega<br/>| systems=Sega Genesis| best=No. We recommend<br/>[[Genesis Plus DC]]| isactive=No| firstversion=n/a| NTSCVGAPAL=All }} The '''Sega Smash Pack Volume 1''' was a compilation of older Sega games for the Dreamcast. A second volume was never released. The majority of the included games were Genesis games, while ''Virtua Cop 2'' was a port of the PC version (which was a port of the Saturn arcade port) and [[Sega Swirl]] was a Dreamcast-original game that was also included on the [[PlanetWeb]] web browser. The games on the compilation include Altered Beast, Columns, Golden Axe, Phantasy Star II, Revenge of Shinobi, Sega Swirl, Shining Force, Vectorman, Sonic the Hedgehog, Streets of Rage 2, Virtua Cop 2, and Wrestle War. =Emulation= The Genesis games available in this compilation were playable by means of emulation. Three days after the disc was released in North America, the pirate group [[Echelon]] released a [[warez]] copy of the game. In the [http://dcemulation.org/files/emulators/esmpkrl/e-smshpk.nfo release notes], they noted that it is possible to create a loader for the emulator to play any Genesis ROM. Mysteriously, an "Uncle Sonic" was given thanks in the release notes. Two days later, Echelon [http://dcemulation.org/files/emulators/esmpkrl/e-smpkrl.nfo released the emulator binaries] with its own frontend menu system so that users could put their own [[ROMs]] on a disc and play any Genesis games. While the group warned that the loader was a quick coding job and they were not into emulation, the loader was criticized for its hard-to-read text and lack of stability. In response, CrowTRobo of the software group [[Obsidian]] wrote a loader which they called the '''Lemec Loader''', which addressed these issues and contained additional features. Although the emulator was fullspeed, it has been criticized for its very poor sound emulation and its lack of compatibility with certain key titles like ''Sonic The Hedgehog 2''. The emulator is not provided here because of copyright issues. It was later revealed that [[Gary Lake]], the programmer for the Sega Smash Pack, included a file on the retail GD-ROM named [http://dcemulation.org/files/emulators/esmpkrl/ECHELON.TXT ECHELON.TXT], which spoke to the group about releasing an emulator loader frontend and took a shot at Sony, who had just defeated Sega in the console wars of that generation. In the text file, Gary references an "Uncle Sonic," which explains the shout-out in the original Smash Pack warez release. [[Image:Smashpk_ech.jpg|thumb|left|200px|Echelon loader]][[Image:Smashpk_obs.jpg|thumb|left|200px|Obsidian's Lemec loader]] fb4d9ab263fa2abad7b3b66488a4bf2a6f04c6fd MediaWiki:Sidebar 8 10 1973 517 2023-03-01T20:04:23Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|Dreamcast Wiki Home ** forums-url|DCEmu Forums ** simulant-discord-url|Simulant Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair ** Emulators on Dreamcast|Emulators * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES eb247e0084303102550450ea859e087058c58f84 File:Superfamicast.jpg 6 827 1974 2023-03-01T20:05:08Z Unknown user 0 wikitext text/x-wiki Super Famicast 607c828a8e84081c2f8ce8ef38dadcc9ecce3967 Super Famicast 0 828 1975 2023-03-01T20:05:16Z Unknown user 0 Created page with "= Super Famicast = {{Infobox_Emulator_Information| name=Super Famicast| image=[[Image:superfamicast.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/www.super..." wikitext text/x-wiki = Super Famicast = {{Infobox_Emulator_Information| name=Super Famicast| image=[[Image:superfamicast.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/www.superfamicast.com/ Homepage]| version=2.0| downloads=[http://dcemulation.org/files/emulators/SuperFamicast_V1(DJ).zip DiscJuggler(V1)]<br/>[http://dcemulation.org/files/emulators/SuperFamicast_V2(DJ).zip DiscJuggler (V2)]<br/>[http://dcemulation.org/files/emulators/SuperFamicast_V1(Nero).zip Nero (V1)]<br/>[http://dcemulation.org/files/emulators/SuperFamicast_V2(Nero).zip Nero (V2)]<br/>[http://dcemulation.org/files/emulators/SuperFamicast_V1(Plain).zip Plain Files(V1)]<br/>[http://dcemulation.org/files/emulators/SuperFamicast_V2(Plain).zip Plain Files(V2)] <br/>[http://dcemulation.org/files/emulators/SuperFamicast_V1(Plain).zip Source Code (v1)]<br/> [http://dcemulation.org/files/emulators/SuperFamicast_V2(Source).zip Source Code (V2)]| release date=1/30/2004| author=[[Scherzo]]<br/>| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Super Famicast is a Super Nintendo emulator ported and coded by [[Scherzo]] using GCC and the KOS Development Library. Super Famicast is considered to be one of the best Super Nintendo emulators on the [[Dreamcast]] console, second only to [[DreamSNES]]. SFC v1 currently is the fastest SNES emulator for Dreamcast if sound emulation is deactivated in options, while SFC v2 offers the best high quality SNES sound emulation on DC. It's suggested that you put both versions on one disc with [[SBInducer]] v4. '''Features:''' *Many games emulate at fullspeed with frame skipping. *Load ROMs from CD; disc swapping and .ZIP format supported *Sound *Save SRAM to VMU *Adjustable screen *Theme system including background music *Save emulator settings to VMU '''Links:''' '''Official Website:''' http://www.superfamicast.com/ '''SelfbootInducer SBI Downloads:''' http://www.dchelp.net/sbi/ [[category: emulator]] e571bb735b51a69383ba39678b7454bf1f4cdd76 File:Dreamsnesmainmenu.jpg 6 829 1976 2023-03-01T20:06:19Z Unknown user 0 wikitext text/x-wiki DreamSNES Main Menu f38de866b3d908e3b8434a1b951f1488891b0f98 DreamSNES 0 830 1977 2023-03-01T20:06:27Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DreamSNES| image=[[Image:Dreamsnesmainmenu.jpg|center|250px]]| homepage=[http://mc.pp.se/dc/dreamsnes/ Homepage]| version=0.9.8| down..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSNES| image=[[Image:Dreamsnesmainmenu.jpg|center|250px]]| homepage=[http://mc.pp.se/dc/dreamsnes/ Homepage]| version=0.9.8| downloads=[http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files]<br/>| release date=10/31/2002| author=[[Marcus Comstedt]]<br/>[[Peter Bortas]]<br/>[[Per Hedbor]]<br/>| original=Snes9x<br/>(Snes9x Team)| systems=Super Nintendo| best=No, try<br/>[[SNES4All|Snes4All]]| refreshrate=50Hz/60Hz| isactive=No }} ==History== DreamSNES is a port of the Snes9x [[Super NES]] emulator for Dreamcast, developed by [[Marcus Comstedt]], [[Peter Bortas]], and [[Per Hedbor]]. It is not completely fullspeed, but it can run near-fullspeed with some tweaking. It features capabilities to save games to the VMU, an optional TV-mode for creating a TV-like feel when being played on a VGA monitor, four controller support, mouse, keyboard, and lightgun support, hidden games, ROMs list support, great artwork by Kathy Choi, and groovy music by Jan Warnstam. It was translated to a high number of languages, including Finnish, French, German, Italian, Japanese, Polish, Portuguese, Romanian, Spanish, and Swedish. It was the best Snes emulator on the Dreamcast scene for many years, leaving behind a secure legacy. =Downloads= * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files] * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8-cdi.zip DiscJuggler] * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8-nero.zip Nero] * 0.9.7 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.7.zip Plain Files] =Related tools= * [http://dcemulation.org/1-newsdump/emulators/dreamsnes/Provlist.zip Provlist]<br /> * [http://dcemulation.org/1-newsdump/emulators/dreamsnes/romlst-1.2.zip RomList] =Links= * [http://www.lysator.liu.se/dreamsnes/tutorial/ Burning tutorial written by the DreamSNES team]<br /> * [http://peter.bortas.org/dreamsnes/faq.html Official DreamSNES FAQ]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21208 Bug/compatability list]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21518 nakamichi's bug/compatibility list] [[Category:Emulator]] c7084ab8a0ccab0353c15b934c15c96fb55ed0d2 1978 1977 2023-03-01T20:06:33Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSNES| image=[[File:Dreamsnesmainmenu.jpg|center|250px]]| homepage=[http://mc.pp.se/dc/dreamsnes/ Homepage]| version=0.9.8| downloads=[http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files]<br/>| release date=10/31/2002| author=[[Marcus Comstedt]]<br/>[[Peter Bortas]]<br/>[[Per Hedbor]]<br/>| original=Snes9x<br/>(Snes9x Team)| systems=Super Nintendo| best=No, try<br/>[[SNES4All|Snes4All]]| refreshrate=50Hz/60Hz| isactive=No }} ==History== DreamSNES is a port of the Snes9x [[Super NES]] emulator for Dreamcast, developed by [[Marcus Comstedt]], [[Peter Bortas]], and [[Per Hedbor]]. It is not completely fullspeed, but it can run near-fullspeed with some tweaking. It features capabilities to save games to the VMU, an optional TV-mode for creating a TV-like feel when being played on a VGA monitor, four controller support, mouse, keyboard, and lightgun support, hidden games, ROMs list support, great artwork by Kathy Choi, and groovy music by Jan Warnstam. It was translated to a high number of languages, including Finnish, French, German, Italian, Japanese, Polish, Portuguese, Romanian, Spanish, and Swedish. It was the best Snes emulator on the Dreamcast scene for many years, leaving behind a secure legacy. =Downloads= * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files] * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8-cdi.zip DiscJuggler] * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8-nero.zip Nero] * 0.9.7 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.7.zip Plain Files] =Related tools= * [http://dcemulation.org/1-newsdump/emulators/dreamsnes/Provlist.zip Provlist]<br /> * [http://dcemulation.org/1-newsdump/emulators/dreamsnes/romlst-1.2.zip RomList] =Links= * [http://www.lysator.liu.se/dreamsnes/tutorial/ Burning tutorial written by the DreamSNES team]<br /> * [http://peter.bortas.org/dreamsnes/faq.html Official DreamSNES FAQ]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21208 Bug/compatability list]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21518 nakamichi's bug/compatibility list] [[Category:Emulator]] d4a6212d9a82955f6ae6483b6c8f6424697c9204 File:Ngine-snes9x1.jpg 6 831 1979 2023-03-01T20:07:40Z Unknown user 0 wikitext text/x-wiki Ngine-snes9x1 93710e98097c1d9f17fe445981bdc985fe6353d6 File:Ngine-snes9x3.jpg 6 832 1980 2023-03-01T20:07:46Z Unknown user 0 wikitext text/x-wiki Ngine-snes9x3 88e632a74386b72446b3b8eeeacf648d509e81a6 File:Ngine-snes9x4.jpg 6 833 1981 2023-03-01T20:07:53Z Unknown user 0 wikitext text/x-wiki Ngine-snes9x4 3e7de3b5b3258fc9244dd4e90f60764670335c5a Ngine SNES9x 0 834 1982 2023-03-01T20:07:58Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Ngine SNES9x| image=[[Image:Ngine-snes9x4.jpg]]| homepage=[http://www.ngine.de/ Homepage]| version=V0.40| downloads=[http://ww..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Ngine SNES9x| image=[[Image:Ngine-snes9x4.jpg]]| homepage=[http://www.ngine.de/ Homepage]| version=V0.40| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/ngine-snes9x-0-40.zip Disk Juggler] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/ngine-snes9x-0.40n.zip Nero] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/ngine-snes9x-0-40-binary-only.zip Binary Only] <br/>| release date=04/25/04| author=Tubooboo| original=Snes9x / Ngine Format| systems=SNES| best=Yes.| isactive=No }} Developer: [http://www.ngine.de/ Tubooboo] Version: 0.40 Last Updated: 03-22-01 A multiplatform operating system that is easy to port games to a different operating system and platforms. This specifically is a Snes9x Port using this Ngine format. [[Image:Ngine-snes9x1.jpg]] [[Image:Ngine-snes9x3.jpg]] Status: 50% to 80% speed depending on the game. No sound. =Old Versions= [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/nginesnes9xdj3.zip Disk Juggler] Old version .30a [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/nginesnes9xnero.zip Nero] Old version .30a [[Category:Emulator]] a7f0cfd836922b49a7b903610f5553fb7cd277e1 File:Sintendo.jpg 6 835 1983 2023-03-01T20:08:53Z Unknown user 0 wikitext text/x-wiki Sintendo a93fde4b8c5225237e2424b93e4c54b25a7f32d1 Sintendo 0 836 1984 2023-03-01T20:08:57Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Sintendo| image=[[Image:sintendo.jpg|center|250px]]| homepage=[http://sintendo.dcemulation.org/ Homepage]| version=0.10-pre2| downloa..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Sintendo| image=[[Image:sintendo.jpg|center|250px]]| homepage=[http://sintendo.dcemulation.org/ Homepage]| version=0.10-pre2| downloads=[http://sintendo.dcemulation.org/files/BetaTest010-2.zip Plain Files]<br/>[http://sintendo.dcemulation.org/files/Sintendo-Source-August-18-2001.zip Source code]| release date=08/03/2001| author=Jamin Vander Berg (aka [[Sin]])| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} Sintendo was one of the earliest emulators for the Dreamcast console. It it a port of Snes9x by Jamin Vander Berg (aka [[Sin]]). It was made using the [[WinCE]] SDK. The newest version is Sintendo Beta v0.10 - Prerelease version 2 which was released on August 3, 2001. The Sintendo website is hosted by DCEmulation.com. Sintendo doesn't support sound or saving games. [[Sin]] planned to include both in a future version of Sintendo but he never released it. Here's some status information by [[Sin]]: *Memory allocation is working. *Port to dreamcast successfull. Little slow at the moment. *Features done are MOD emulation, Joystick Support and saving. *Little bit of sound and graphics done. Old versions of Sintendo can be downloaded from [http://sintendo.dcemulation.org/ the official site]. The official forums are still up, but hadn't had any activity since years. They can be found [http://pub21.ezboard.com/bdcsnes here] but all previous posts have gone lost. == Activity == Below is a post from [[Sin]] that he made on 27th December 2002. It is one of last posts he made in his own forum. His last post there was on 22th January 2003 responding to someone who had replied to this message. He has never been active again in any Dreamcast forum. The original topic can be found [http://web.petabox.bibalex.org/web/20041217131810/p210.ezboard.com/fdcsnesdcsnes.showMessage?topicID=99.topic here]. ''It has been a great deal of time since I have updated this website, reviewed the posts here, or even touched the code for Sintendo.'' ''In recent ponderings, I have wondered if what I have done is worth working further forward towards. While I am deeply satisfied with how far everything has come (some may not agree, but I doubt they are programmers), I still never got it as far as I had hoped.'' ''The Dreamcast is all but a dead system. Many of us still use ours, I pop a disc in and play from time to time, but all of the effort I've put into Sintendo in the past, while not wasted, may fall on deaf ears if I continue to pursue the project, so long after the consoles unfortunate demise.'' ''Work, as always, is a burden on a creative programmer's time and imagination. I'll not use that as an excuse for anything. I still program from time to time, but its been quite a while since I've approached anything that compares with the scope of Sintendo.'' ''Never before or since have I conceived a project with such determination to see it through to even as close a level of completion. Anyone who programs (and some who don't) should understand the year plus of plight that went into this project. I appreciate all of the support I have received over this time. I gratefully appreciate my host, dcemulation.com, for keeping this site up more than a year after a single update.'' ''I am by no means saying that Sintendo is a dead project. I am not quitting, per se. I am only trying to tell all of you, what few dedicated followers I may have left, that I have not worked on it for quite some time, and can't necessarily forsee any time in the future when I will. I can not even promise that Sintendo *will* ever be worked on (by me at least), but I'd like to think that that's not the case.'' ''I have been dedicated to games programming since the age of 15. Now, 25, I still work towards the same goal. Sintendo bore me priceless experience in the console programming market that I will take with me in the future. Where it will lead? I can't say for certain. I'd like to develop games for many years to come. Personally, and most importantly, I'd like to develop a game to completion. Perhaps we may some day see Sintendo on another console (although I currently own none to port it to). Time will tell.'' ''Thank you all again for all the support I've received. I apologize for lack of adequete postings as well as lack of decisiveness.'' ''Until another time,'' ''Sin'' == Interview == This is an interview with [[Sin]], the creator of Sintendo. It was taken in late 2001 by Emulation-X of GeoShock, a popular emulation site in these days. GeoShock went offline in early 2006, so we have published this interview here. '''Emulation-X: Why did you make Sintendo?''' Sin: I made Sintendo because I wanted to be able to play Super Nintendo games on my Dreamcast. I released Sintendo to the world because I imagined other people would like to as well. There was once a time when such a thing was only imaginable and I saw that I *could* do it... I used Snes9x because it is portable, maybe the development a lot easier The only other really useful SNES emulator is ZSNES, which may be better in some ways, but is far from portable. ZSNES is written primarily in x86 assembly, everything written in that way must be re-written to work on the Dreamcast. Snes9x was just a much more attractive option because it's written in C.I have had to do very little re-writing of the Snes9x code. I started most of my research on the forums of the "warez" sites. Dcisos.com had a development forum The portable version of Snes9x has a file called how2port.txt. Its like following instructions, kind of It's quite a bit more complicated than that. '''Emulation-X: Who made the a big Impact with you while making Sintendo?''' Sin: I'd have to say Gary, the author of Snes9x had a huge impact on me.The fact that he responded to my email suprised me, and while he hasn't given me any particular help... He has been very supportive...as well as creating the thing in the first place. Tubooboo has helped me solve a few of my most frustrating problems. Tubooboo's presence on the scene was also a great motivating force i wish a great deal of success to him with his project. '''Emulation-X: Tubooboo also has a Snes Emulator for the Dreamcast. Was this a race?''' Sin: The fact that he started it, however, spurred a great deal of competitiveness in me that was probably the direct cause of Sintendo being released on time there was probably an unspoken race between us. the race ended when Marcus won, by a half a day I released my emulator later that day, and then an improved version the next. It has sound and saving, two great feats,but I understand that the sound slows down the emulation somewhat and speed in controlled by a frameskip, which takes away some of the smoothness from the games. '''EMULATION-X: When did you get involved in Emulation?''' Sin: I don't know when really maybe around Nesticle.It ran on our P100 at good speed, it was fun to play all those old games even my mom loved it. Then emulators started coming out that emulated the SNES following in a loose sense of the term. I've used a lot of them,I've even considered doing SNES emulation myself. I had a few ideas but never the time to research all the ins and outs the SNES is a very complicated machine.I used to imagine that compiling a SNES cartridge into machine code would speed emulation a great deal...and it probably would...it is unfortunately not very practical . '''EMULATION-X: Besides making Sintendo (Snes for DC) are there any other Emulators that you might want to port in the future to the Dreamcast?''' Sin: I don't have any intention on porting another emulator to the DC.Though SNES emulation on the PS2 would be very cool...and certainly be less problematic that my orignal port I haven't exactly decided yet. I am a games programmer at heart. I love RPGs in specific and I can't play one without analysing it a great deal I've been programming rudementary RPGs since I first started programming and it is perhaps the reason I began programming in the first place. So I guess there's a good chance that may be my next route '''Emulation-X: What other Emus do you use besides Snes9x?''' Sin: I kind of like Pokemon, so sometimes I use the no$gb emulator, or whatever on the PC version you can run more than one gameboy...which makes trading useful, and I programmed a small app that switches the save files arround so I can play more than one save... and if I click one check box, I can trade without actually losing the pokemon I traded (i.e. Copy a Pokemon) '''EMULATION-X: What is your View on Utopia boot disk (DC-warez) and the hole shut down of the DC news web sites?''' Sin: The boot disk is a good thing, and I don't believe it is really illegal. News sites are news sites, and Sega has no right toshut them down for providing information regardless of the nature of that information '''EMULATION-X: Has Sega or Nintendo never tried to contact you ?''' Sin: No, but I have considered contacting them. Perhaps obtain a license for Sintendo... or get a job :) or licensing for future projects like the aforementioned RPG its an option i am looking into I'd imagine the people that use it for emulation will be using it for some time to come '''Emulation-X: What do you think about the Dreamcast Now?''' Sin: As a consumer system, it's closed to dead. No one really wants to spend any money on it any more the games have been released (illegally) for free. '''EMULATION-X: Do you think that Emulation and Warez kills a system?''' Sin: Yes and no. Warez killed a lot of profits Sega and its developers could have made. But then all those kids bought tons of accessories because they had extra money. Emulation is a program I don't think in and of itself emulation and emulators for the Dreamcast could kill the system But then, it's kindof like cheating at a game... You played it for a while and you're bored... so you want something new... So you cheat to make it more exciting... eventually (maybe sooner, maybe later) thats gets old too... but the game was already old in the first place if you catch my analogy, but I know I'll stick pick up my Dreamcast for years to come and play some old SNES games . '''EMULATION-X: Where did the name Sintendo come from?''' Sin: spankthemonkey, my web designer, thought of it. '''EMULATION-X: Do you plan on improving on Sintendo anytime soon?''' Sin: I'm still improving Sintendo almost every day there's a lot that still has to be done speed is an issue, no one wants to play a game (at least not for a great deal of time) if it's slow, saving should be implemented soon and I really want to be able to hear the music for ChronoTrigger while I'm playing. There are a few details that were left out from my first release I am covering those bases (and maybe throwing in a few extras) and I'll release in under a week. '''EMULATION-X: What type of ideas might you add to the Menu system?''' Sin: An in-game menu has already been done (but still a little buggy) I have to fix it so it shows the last file and so it doesn't crash if you don't have enough files then I may add the ability to browse folders, both to improve the organization, and to add to the maximum number of ROMs per CD. '''EMULATION-X: Right now the maximum is 128?''' Sin: Well, technically 127 :) but yes..... with folders, each folder will be able to have up to 128 files so the number of ROMs possible is nearly infinite (up to the storage capacity of a CD) other than that, I'm trying to add a small speed increase. '''EMULATION-X: Thank you Sin for taking the time to answer all of My Questions, I really hope that anyone that reads this can understand what dedication you have and that this is only your hobby and you don't get paid to do this.''' Sin: Well, thank you for taking the time to interview little old me :) I hope Everyone will enjoy emulation on the Dreamcast :) [[Category:Emulator]] 89e5331aaac3939abf08540272e0059a3c224e54 1985 1984 2023-03-01T20:09:02Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Sintendo| image=[[File:sintendo.jpg|center|250px]]| homepage=[http://sintendo.dcemulation.org/ Homepage]| version=0.10-pre2| downloads=[http://sintendo.dcemulation.org/files/BetaTest010-2.zip Plain Files]<br/>[http://sintendo.dcemulation.org/files/Sintendo-Source-August-18-2001.zip Source code]| release date=08/03/2001| author=Jamin Vander Berg (aka [[Sin]])| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} Sintendo was one of the earliest emulators for the Dreamcast console. It it a port of Snes9x by Jamin Vander Berg (aka [[Sin]]). It was made using the [[WinCE]] SDK. The newest version is Sintendo Beta v0.10 - Prerelease version 2 which was released on August 3, 2001. The Sintendo website is hosted by DCEmulation.com. Sintendo doesn't support sound or saving games. [[Sin]] planned to include both in a future version of Sintendo but he never released it. Here's some status information by [[Sin]]: *Memory allocation is working. *Port to dreamcast successfull. Little slow at the moment. *Features done are MOD emulation, Joystick Support and saving. *Little bit of sound and graphics done. Old versions of Sintendo can be downloaded from [http://sintendo.dcemulation.org/ the official site]. The official forums are still up, but hadn't had any activity since years. They can be found [http://pub21.ezboard.com/bdcsnes here] but all previous posts have gone lost. == Activity == Below is a post from [[Sin]] that he made on 27th December 2002. It is one of last posts he made in his own forum. His last post there was on 22th January 2003 responding to someone who had replied to this message. He has never been active again in any Dreamcast forum. The original topic can be found [http://web.petabox.bibalex.org/web/20041217131810/p210.ezboard.com/fdcsnesdcsnes.showMessage?topicID=99.topic here]. ''It has been a great deal of time since I have updated this website, reviewed the posts here, or even touched the code for Sintendo.'' ''In recent ponderings, I have wondered if what I have done is worth working further forward towards. While I am deeply satisfied with how far everything has come (some may not agree, but I doubt they are programmers), I still never got it as far as I had hoped.'' ''The Dreamcast is all but a dead system. Many of us still use ours, I pop a disc in and play from time to time, but all of the effort I've put into Sintendo in the past, while not wasted, may fall on deaf ears if I continue to pursue the project, so long after the consoles unfortunate demise.'' ''Work, as always, is a burden on a creative programmer's time and imagination. I'll not use that as an excuse for anything. I still program from time to time, but its been quite a while since I've approached anything that compares with the scope of Sintendo.'' ''Never before or since have I conceived a project with such determination to see it through to even as close a level of completion. Anyone who programs (and some who don't) should understand the year plus of plight that went into this project. I appreciate all of the support I have received over this time. I gratefully appreciate my host, dcemulation.com, for keeping this site up more than a year after a single update.'' ''I am by no means saying that Sintendo is a dead project. I am not quitting, per se. I am only trying to tell all of you, what few dedicated followers I may have left, that I have not worked on it for quite some time, and can't necessarily forsee any time in the future when I will. I can not even promise that Sintendo *will* ever be worked on (by me at least), but I'd like to think that that's not the case.'' ''I have been dedicated to games programming since the age of 15. Now, 25, I still work towards the same goal. Sintendo bore me priceless experience in the console programming market that I will take with me in the future. Where it will lead? I can't say for certain. I'd like to develop games for many years to come. Personally, and most importantly, I'd like to develop a game to completion. Perhaps we may some day see Sintendo on another console (although I currently own none to port it to). Time will tell.'' ''Thank you all again for all the support I've received. I apologize for lack of adequete postings as well as lack of decisiveness.'' ''Until another time,'' ''Sin'' == Interview == This is an interview with [[Sin]], the creator of Sintendo. It was taken in late 2001 by Emulation-X of GeoShock, a popular emulation site in these days. GeoShock went offline in early 2006, so we have published this interview here. '''Emulation-X: Why did you make Sintendo?''' Sin: I made Sintendo because I wanted to be able to play Super Nintendo games on my Dreamcast. I released Sintendo to the world because I imagined other people would like to as well. There was once a time when such a thing was only imaginable and I saw that I *could* do it... I used Snes9x because it is portable, maybe the development a lot easier The only other really useful SNES emulator is ZSNES, which may be better in some ways, but is far from portable. ZSNES is written primarily in x86 assembly, everything written in that way must be re-written to work on the Dreamcast. Snes9x was just a much more attractive option because it's written in C.I have had to do very little re-writing of the Snes9x code. I started most of my research on the forums of the "warez" sites. Dcisos.com had a development forum The portable version of Snes9x has a file called how2port.txt. Its like following instructions, kind of It's quite a bit more complicated than that. '''Emulation-X: Who made the a big Impact with you while making Sintendo?''' Sin: I'd have to say Gary, the author of Snes9x had a huge impact on me.The fact that he responded to my email suprised me, and while he hasn't given me any particular help... He has been very supportive...as well as creating the thing in the first place. Tubooboo has helped me solve a few of my most frustrating problems. Tubooboo's presence on the scene was also a great motivating force i wish a great deal of success to him with his project. '''Emulation-X: Tubooboo also has a Snes Emulator for the Dreamcast. Was this a race?''' Sin: The fact that he started it, however, spurred a great deal of competitiveness in me that was probably the direct cause of Sintendo being released on time there was probably an unspoken race between us. the race ended when Marcus won, by a half a day I released my emulator later that day, and then an improved version the next. It has sound and saving, two great feats,but I understand that the sound slows down the emulation somewhat and speed in controlled by a frameskip, which takes away some of the smoothness from the games. '''EMULATION-X: When did you get involved in Emulation?''' Sin: I don't know when really maybe around Nesticle.It ran on our P100 at good speed, it was fun to play all those old games even my mom loved it. Then emulators started coming out that emulated the SNES following in a loose sense of the term. I've used a lot of them,I've even considered doing SNES emulation myself. I had a few ideas but never the time to research all the ins and outs the SNES is a very complicated machine.I used to imagine that compiling a SNES cartridge into machine code would speed emulation a great deal...and it probably would...it is unfortunately not very practical . '''EMULATION-X: Besides making Sintendo (Snes for DC) are there any other Emulators that you might want to port in the future to the Dreamcast?''' Sin: I don't have any intention on porting another emulator to the DC.Though SNES emulation on the PS2 would be very cool...and certainly be less problematic that my orignal port I haven't exactly decided yet. I am a games programmer at heart. I love RPGs in specific and I can't play one without analysing it a great deal I've been programming rudementary RPGs since I first started programming and it is perhaps the reason I began programming in the first place. So I guess there's a good chance that may be my next route '''Emulation-X: What other Emus do you use besides Snes9x?''' Sin: I kind of like Pokemon, so sometimes I use the no$gb emulator, or whatever on the PC version you can run more than one gameboy...which makes trading useful, and I programmed a small app that switches the save files arround so I can play more than one save... and if I click one check box, I can trade without actually losing the pokemon I traded (i.e. Copy a Pokemon) '''EMULATION-X: What is your View on Utopia boot disk (DC-warez) and the hole shut down of the DC news web sites?''' Sin: The boot disk is a good thing, and I don't believe it is really illegal. News sites are news sites, and Sega has no right toshut them down for providing information regardless of the nature of that information '''EMULATION-X: Has Sega or Nintendo never tried to contact you ?''' Sin: No, but I have considered contacting them. Perhaps obtain a license for Sintendo... or get a job :) or licensing for future projects like the aforementioned RPG its an option i am looking into I'd imagine the people that use it for emulation will be using it for some time to come '''Emulation-X: What do you think about the Dreamcast Now?''' Sin: As a consumer system, it's closed to dead. No one really wants to spend any money on it any more the games have been released (illegally) for free. '''EMULATION-X: Do you think that Emulation and Warez kills a system?''' Sin: Yes and no. Warez killed a lot of profits Sega and its developers could have made. But then all those kids bought tons of accessories because they had extra money. Emulation is a program I don't think in and of itself emulation and emulators for the Dreamcast could kill the system But then, it's kindof like cheating at a game... You played it for a while and you're bored... so you want something new... So you cheat to make it more exciting... eventually (maybe sooner, maybe later) thats gets old too... but the game was already old in the first place if you catch my analogy, but I know I'll stick pick up my Dreamcast for years to come and play some old SNES games . '''EMULATION-X: Where did the name Sintendo come from?''' Sin: spankthemonkey, my web designer, thought of it. '''EMULATION-X: Do you plan on improving on Sintendo anytime soon?''' Sin: I'm still improving Sintendo almost every day there's a lot that still has to be done speed is an issue, no one wants to play a game (at least not for a great deal of time) if it's slow, saving should be implemented soon and I really want to be able to hear the music for ChronoTrigger while I'm playing. There are a few details that were left out from my first release I am covering those bases (and maybe throwing in a few extras) and I'll release in under a week. '''EMULATION-X: What type of ideas might you add to the Menu system?''' Sin: An in-game menu has already been done (but still a little buggy) I have to fix it so it shows the last file and so it doesn't crash if you don't have enough files then I may add the ability to browse folders, both to improve the organization, and to add to the maximum number of ROMs per CD. '''EMULATION-X: Right now the maximum is 128?''' Sin: Well, technically 127 :) but yes..... with folders, each folder will be able to have up to 128 files so the number of ROMs possible is nearly infinite (up to the storage capacity of a CD) other than that, I'm trying to add a small speed increase. '''EMULATION-X: Thank you Sin for taking the time to answer all of My Questions, I really hope that anyone that reads this can understand what dedication you have and that this is only your hobby and you don't get paid to do this.''' Sin: Well, thank you for taking the time to interview little old me :) I hope Everyone will enjoy emulation on the Dreamcast :) [[Category:Emulator]] 23d4bf5bfb4316afad7042a3086b7a11ac5ed0d2 File:Snes4all.png 6 837 1986 2023-03-01T20:09:37Z Unknown user 0 wikitext text/x-wiki Snes4all 1bacae16303a1e22892fa0526c500d3de7fb59ed SNES4All 0 838 1987 2023-03-01T20:09:42Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SNES4ALL| image=[[Image:snes4all.png|center|250px]]| homepage=[http://chui.dcemu.co.uk/snes4all.html Homepage]| version=Beta 1| downl..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SNES4ALL| image=[[Image:snes4all.png|center|250px]]| homepage=[http://chui.dcemu.co.uk/snes4all.html Homepage]| version=Beta 1| downloads=[http://chui.dcemu.co.uk/releases/snes4all-beta1.rar Plain Files]<br/>[http://chui.dcemu.co.uk/releases/snes4all-src-beta1.tar.bz2 Source Files]<br/>| release date=03/28/2011| author=[[Chui]]| original=[http://www.snes9x Snes9x]<br/>(Snes9x Team)| systems=Super Nintendo| best=Yes| refreshrate=50Hz/60Hz| isactive=Yes| }} ==About== SNES4ALL is a port of Snes9x to the Dreamcast by the very well kown Spanish Dreamcast coder [[Chui]]. ==Features== * Hardware scaled resolution. * Assembler CPUs core enabled. * Auto frameskip for real speed. * Save state and SRAM. * VMU and SD-Card support. * Operative Menu: Throttle, Frameskip, Transparency, Sound * File-manager with sub-directories access. * 4 joysticks emulated. * Under PAL Dreamcasts ask 60-50Hz selection ==Downloads== * ''Beta-1 - [http://chui.dcemu.co.uk/releases/snes4all-beta1.rar Plain Files] - 03/28/2011 * ''Beta-1 - [http://chui.dcemu.co.uk/releases/snes4all-src-beta1.tar.bz2 Source Files] - 03/28/2011 * ''Alpha-3 - [http://www.qfpost.com/download.do?get=bdefe8b78c9c8a2bbacffe01819654d2 Plain Files] - 03/27/2006 * ''Alpha-3 - [http://www.qfpost.com/download.do?get=fea7ed6d0da16994159c8f3a2f4db136 Source Files] - 03/27/2006 * ''Alpha-2 - [http://www.qfpost.com/download.do?get=ce3eb599c5b52d6898e80b7e7f182ad2 Plain Files] - 03/19/2006 * ''Alpha-2 - [http://www.qfpost.com/download.do?get=fd54df6566720888c6c614f50e5ad5bc Source Files] - 03/19/2006 ==Links== * ''[[SNES4All_list|SNES4All Compatibility List]] (Alpha 3) [[Category:Emulator]] 475e756d3dd87abe329d5cc81ce3b4ed3aa965ad 1988 1987 2023-03-01T20:09:48Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SNES4ALL| image=[[File:snes4all.png|center|250px]]| homepage=[http://chui.dcemu.co.uk/snes4all.html Homepage]| version=Beta 1| downloads=[http://chui.dcemu.co.uk/releases/snes4all-beta1.rar Plain Files]<br/>[http://chui.dcemu.co.uk/releases/snes4all-src-beta1.tar.bz2 Source Files]<br/>| release date=03/28/2011| author=[[Chui]]| original=[http://www.snes9x Snes9x]<br/>(Snes9x Team)| systems=Super Nintendo| best=Yes| refreshrate=50Hz/60Hz| isactive=Yes| }} ==About== SNES4ALL is a port of Snes9x to the Dreamcast by the very well kown Spanish Dreamcast coder [[Chui]]. ==Features== * Hardware scaled resolution. * Assembler CPUs core enabled. * Auto frameskip for real speed. * Save state and SRAM. * VMU and SD-Card support. * Operative Menu: Throttle, Frameskip, Transparency, Sound * File-manager with sub-directories access. * 4 joysticks emulated. * Under PAL Dreamcasts ask 60-50Hz selection ==Downloads== * ''Beta-1 - [http://chui.dcemu.co.uk/releases/snes4all-beta1.rar Plain Files] - 03/28/2011 * ''Beta-1 - [http://chui.dcemu.co.uk/releases/snes4all-src-beta1.tar.bz2 Source Files] - 03/28/2011 * ''Alpha-3 - [http://www.qfpost.com/download.do?get=bdefe8b78c9c8a2bbacffe01819654d2 Plain Files] - 03/27/2006 * ''Alpha-3 - [http://www.qfpost.com/download.do?get=fea7ed6d0da16994159c8f3a2f4db136 Source Files] - 03/27/2006 * ''Alpha-2 - [http://www.qfpost.com/download.do?get=ce3eb599c5b52d6898e80b7e7f182ad2 Plain Files] - 03/19/2006 * ''Alpha-2 - [http://www.qfpost.com/download.do?get=fd54df6566720888c6c614f50e5ad5bc Source Files] - 03/19/2006 ==Links== * ''[[SNES4All_list|SNES4All Compatibility List]] (Alpha 3) [[Category:Emulator]] 718d418deb61a35e4b3e0c696b63e562a1b2553d Genesis Plus DC 0 839 1989 2023-03-01T20:11:00Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Genesis Plus / DC| version=07/26/2006| downloads=[http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/Gpdc-gpwt-26072006-BA.z..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Genesis Plus / DC| version=07/26/2006| downloads=[http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/Gpdc-gpwt-26072006-BA.zip GPDC BlackAura]<br>[http://www.dcemulation.org/files/emulators/genplus_dc_01_bin.zip GPDC v01]<br>[http://dcemulation.org/1-newsdump/emulators/genesis/genesisplusdc/genplus_dc_01_src.tar.bz2 Source Code v01]| release date=07/26/06| author=[[BlackAura]]| original=[http://cgfm2.emuviews.com/ GenesisPlus] by<br/>Charles MacDonald| systems=Sega Genesis| best=Yes.| isactive=Yes. }} Genesis Plus/DC is a port of Charles MacDonald's Sega Genesis/MegaDrive emulator, Genesis Plus, to the Dreamcast. It is currently the best available Sega Genesis emulator for the Dreamcast platform.It runs full speed on most games without frameskip with sound disabled. ==Features== * Full speed with full sound (no skipping!) * SRAM Saving to VMU * Great compatibility * 2 player support * 6 button pad support * Region settings (JP/US/EU) * .GEN, .BIN, .SMD, and .ZIP support * 2 CPU cores, FAME and C68K * Hardware and software rendering * Fixed graphic bugs from PVR3 version * Mono/Stereo settings (via Dreamcast BIOS) * Nice and easy to use GUI * GPDC is [[GPL|free software]] ===Missing Features=== * 4 player support * Frameskip options for the software renderer * Enhanced sound options ==History== GPDC started as a port of Genesis Plus by Charles Mac Donald. It's been in development since 2003 and a lot of progress has been made since then: BlackAura rewrote the video renderer for the Dreamcast's PowerVR2. Stef D of [http://gens.consolemul.com/ wGens] fame joined the project in 2004 to contribute fast and accurate CPU emulators: C68K & CZ80. Now with Fox68K's new SH4 Z80 emulator FAZE, and FAME, a 68K emulator written in Dreamcast's SH4 assembly language, and BlackAura working on sound emulation, the project has reached its final stage. An official release is expected for the end of this year. ===GPWT=== Until then there's the preview version of GenesisPlusDC Warmtoe & BlackAura released in 07/2006. It is called "GPWT" because it's been the first version to introduce a new GUI written by Warmtoe. ==Controls== ===Button Layout=== *Mega Drive A-Button: (X) *Mega Drive B-Button: (A) *Mega Drive C-Button: (B) *Mega Drive X-Button: (L) *Mega Drive Y-Button: (Y) *Mega Drive Z-Button: (R) *Mega Drive Start-Button: (Start) To exit a running game press (L) + (R) + (Start). ===In the Menu=== (Start) loads a game. Pressing + holding (Up)/(Down) scrolls through your game list. You can skip pages with (Left)/(Right) on the d-pad. To disable/enable 6 button support, press (X). To change the region settings, press (L). ===CPU Settings=== Some details about the different settings: Pressing (B) at the menu changes the CPU emulator. You can select either '''FAME''' - [http://www.m68k.com/fame/ Fox68k]'s great SH4 M68K emulator for fastest emulation, or '''C68K''' - [http://gens.consolemul.com/ Stef D]'s fast and accurate M68K emulator for better compatibility. ===Video Settings=== Press (A) to toggle the graphics renderer. You can select either '''HW''' - Hardware renderer written by BlackAura, using the Dreamcast's PowerVR II DC, very fast but inaccurate in a few games, or '''SW''' - Standard software renderer of GenesisPlusDC by Charles MacDonald, 100% accurate but much slower. ===Recommend Settings=== Recommend settings would be 'Render: HW' with 'CPU: FAME' - if this doesn't work for your game, try 'Render: HW' with 'CPU: C68K' (which is the default setting). ==ROMS.TXT== ===Method 1: Manual creation=== Make sure to rename the actual '.gen', '.bin', or '.zip' roms to not have spaces. ''Examples that'll work:'' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''Comix_Zone_(U)_[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone(U)[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone.bin'''' '''''The rest is straight from the readme:''''' In GPWT there is no directory browsing - just that fixed list of names for that fixed list of games. You put your (zipped) ROMS in the directory: \gpwt\data\ROMS It also expects to find a file: \gpwt\data\ROMS.txt In ROMS.TXT you can put the names of your games in there plus the name you'd like to see displayed on screen: SHINOBI.ZIP The Revenge of Shinobi 'SHINOBI.ZIP' (or 'shinobi.zip') would be your actual ROM, 'The Revenge of Shinobi' will be displayed on screen. Each file + name goes into a seperate line in ROMS.TXT. ===Method 2: Provlist by burnerO=== First download this: *Tool Set - [http://www.dcevolution.net/dsdevelopment/large/CE/gpwt-tools.zip Zipfile] Included are Provlist & Renamer which both are needed. 1. Copy your ROMs (*.zip) in /gpwt/data/ROMS/ and run Provlst.exe 2. Open ROMS.LST in Wordpad and replace ".SMC:" with ".ZIP " (space). 3. Save as 'ROMS.TXT' in /gpwt/data/ 4. Right-click on your /gpwt/data/ROMS/ folder and start Renamer 5. Click on 'Edit' -> 'Multi-Change' and replace "%a.SMC" with "%a.ZIP" 6. Click on 'A->B' to apply the changes and then close Renamer ===Method 3: Romlister by Smurph=== Download this application first: *Romlister - [http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Zipfile] 1. Zip all your roms. Keep them in a separate folder apart from the Plainfiles, or SBI, directories. 2. Start the rom lister. 3. Select the ''''data'''' subfolder from the the extracted Plainfiles, or SBI, packages. 4. Select your folder containing your zipped roms, and click on the 'Process' button. ==How To Burn== A little tutorial: ===Using Selfboot Inducer=== *1. At first you need to download [http://sbibuilder.dc-france.com/download/?idsys=2&idcat=15&idfile=115 Selfboot Inducer v4] and install it into C:/SBInducr/. *2. Then download a SBI for one of the GenesisPlusDC versions [http://www.dchelp.net/sbi HERE]. *3. Put this file into your C:/SBInducr/SBI/ folder. *4. Start C:/SBInducr/SBInducer.exe and check the SBI file showing up on the right window. Then select either "Single Menu" or "SBI2Boot" and click on 'Extract SBI'. *5. Browse to the C:/SBInducr/Inducer/gpwt/tools/ directory to find some tools. *6. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *7. Click on the 'CDRecord' button to burn the CD directly, or on the 'DiscJuggler' button to create a '.cdi' image. ===Using BootDreams=== *1. Download Bootdreams from http://dchelp.dcemulation.org, and install it. *2. Extract the plainfiles to their own folder. *3. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *4. Start Bootdreams. *5. Select the folder containing the plainfiles ''''''1st_read.bin''''''. *6. Choose your image type: '''''CDI''''', '''''NRG''''', or '''''MDF/MDS'''''. *7. Click on the process button. *8. Burn the image with your application of choice. To burn straight off Bootdreams, without creating an image, select the "CdRecord" option. To use the Bootdream's image burner select the "ImgRecord" option. ==Downloads== *[http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/Gpdc-gpwt-26072006-BA.zip Plainfiles] - BlackAura - 07/26/06 *[http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/gpdcq-012007.zip Plainfiles] - Quzar - 01/28/07 * Selfboot Inducer Versions: ''(To put both on one disc)'' **[http://dchelp.net/cgi-bin/sbi/browse/browse.cgi?browse&Emus Browse DCHelp's SBI File Repository] The files are called 'GenesisPlusDC-gpwt-260706-BlackAura.sbi', and 'GenesisPlusDC-gpwt-280107-Quzar.sbi'. ==Compatibility== Lists can be found here ''(W.I.P.)'': *[[GenesisPlusDC_BlackAura_list|GenesisPlusDC (BlackAura)]] 10d0bbfaf9a30c2e49bf798e5e197d91b5f890cb GenesisPlusDC BlackAura list 0 840 1990 2023-03-01T20:11:30Z Unknown user 0 Created page with "===''W.I.P. compatibility list for [[BlackAura]] version of [[Genesis Plus DC]]''.=== ---- Please post the ROM name based on Cowering's GoodTools naming standard (GoodGen)...." wikitext text/x-wiki ===''W.I.P. compatibility list for [[BlackAura]] version of [[Genesis Plus DC]]''.=== ---- Please post the ROM name based on Cowering's GoodTools naming standard (GoodGen). Only verified good dumps (marked with [!] or [c]) will be of any help. Reports about verified bad dumps (marked with [b]) are not helpful at all, and the same applies to hacks or alternate dumps (marked with [h], [t] or [a]). Although reports could be interesting, if the verified good dump doesn't work, but an alternative does. Please post which CPU emu you've used (FAME or C68K). Put a hyphen (-) if you haven't tested a game with FAME or C68K yet. ====Here are the main 4 possible settings:==== *C68K: - HW - *C68K: - SW - *FAME: - HW - *FAME: - SW - ====Specific games must have these settings enabled:==== *3 button controller *Auto region **Doesn't always work, and you must put it on the region manually. Some games require the proper region for compatability. ====Reporting Notes:==== *"Good" **Seems to be near perfect or that the game was not tested much and seems 90%-near perfect. *"Perfect" **Approximately 99.5%-105% speed, sound and graphics. It also means that it feels like it is 100%. It may contain small graphical gliches not worth mentioning and/or small sound problems. Even could have moments of bogging down. Example: *"Toy Story" **This game runs with perfect graphics under C68K SW, but it sacrifices speed. The thing is it runs 105% fluidly under FAME HW with some large graphical glitches on the first level that do not interfere with gameplay at all. So you are left with the question do I want about 95% speed / sound and perfect graphics or 100%+ speed / sound with a few graphical errors. The choice is yours. ==0-9== 16 Ton (SN) (J) [!] *C68K: - HW - Good (torque222) *C68K: - SW - Good the Graphics are better.(Best Choice) (torque222) *FAME: - HW - Good (torque222) *FAME: - SW - Slower (torque222) 3 Ninjas Kick Back (U) [!] *C68K: - HW - Screen blue only. (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Doesn't Start (torque222) *FAME: - SW - Doesn't Start (torque222) 688 Attack Sub (UE) [!] *C68K: - Perfect (torque222) *FAME: - Perfect (torque222) 777 Casino (Unl)[C] *C68k: - Perfect (torque222) *FAME: - Perfect (torque222) ==A== A Ressha de Gyoukou MD (J) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Near Perfect (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Perfect, sound dinged. (torque222) AAAHH! Real Monsters (UE) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Works (with bug in game) *FAME: - SW - Good but you can vanish when you get hurt (torque222) * Special Note I never found that bug. Aah! Harimanada (J) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Good, a little slow. (torque222) *FAME: - HW - Locks up (torque222) *FAME: - SW - Locks up (torque222) Action 52 (Unl) [!] *C68K: - HW - Perfect (Torque222) *C68K: - SW - Good, sound dinged and video dinged. (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Good, sound dinged and video dinged. Addams Family Values (E) (M3) [!] *C68K: - HW - Graphics/Speed Perfect Sound problem and text not readable. (torque222) *C68K: - SW - Graphics/Near full speed sound problem text readable. (torque222) *FAME: - HW - Locks Up (torque222) *FAME: - SW - Locks Up (torque222) *Better with C68k HW or SW Noise Problem in Game.(torque222) Addams Family, The (UE) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Wierd! (torque222) *FAME: - SW - Wierd! (torque222) Advanced Daisenryaku (J) (REV01) [T+Eng95%_NebelwurferHQ] *C68K: - HW - Perfect (torque222) *C68K: - SW - 65% Cannot see screen! (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Interesting Intro! Cannot see screen! (torque222) Adventures of Batman and Robin, The (JU) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Adventures of Batman and Robin, The (U) [!] *C68K: - HW - Perfect until Major graphic glitches on Mad Hatter boss level (hard but playable) and especially Mr. Freeze level blocking half the screen *C68K: - SW - Perfect a little slow (torque222) *FAME: - HW - Won't Start (torque222) *Fame: - SW - Won't Start (torque222) Adventures of Mighty Max, The (U) [!] *C68K: - HW - Perfect (too fast?) *C68K: - SW - Less Speed, more control and a black out on the space level but just wait it will come back in about 20 seconds. (torque222) *FAME: - HW - Locked up (torque222) *FAME: - SW - Locked up (torque222) Aero Blasters (JU) *C68K: Perfect (torque222) *FAME: Locks up (torque222) Aero the Acro-Bat (U) [c][!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - HW - Locks up Restart Needed! (torque222) *FAME: - SW - Locks Up Restart Needed! (torque222) * Special Note: Must be set to 3 button joystick or correct control is not possible. (torque222) Aero the Acro-Bat 2 (U) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *C68K: - SW - Speed dinged, sound dinged. (torque222) *FAME: - HW - Major Graphical Glitches. (torque222) *FAME: - SW - Major Graphical Glitches. (torque222) Aerobiz (U) [!] *C68K: - Works (torque222) *FAME: - Works (torque222) Aerobiz Supersonic (U) [!] *C68K: - Works (torque222) *FAME: - Works (torque222) After Burner II (U) [!] *C68K: - Works, with bugs in video (funciona mas com bugs de video / Falcon Silva) *FAME: - HW - Great speed small graphical problem.(torque222) *FAME: - SW - Very Good After Burner II (U) [h2] *C68K: - HW - Perfect (torque222) *C68K: - SW - Sound Dinged (torque222) *FAME: - HW - Very Fast Small Graphical Glitch.(torque222) *FAME: - SW - Good. (torque222) Air Buster (U) [c][!] *C68K: - HW - Perfect (but begining screens are slow) (torque222) *C68K: - SW - Speed dinged, sound dinged. (but begining screens are slow) (torque222) *FAME: - HW - Very strange, graphics mess (torque222) *FAME: - SW - Messed Up (torque222) Air Diver (U) [!] *C68K: - *FAME: - Air Diver (J) [p1][h1] *C68K: - HW - Graphical Glitch (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Graphical Glitch (torque222) Aladdin I (U)[!] *C68K: - HW - Good (torque222) *C68K: - SW - Speed dinged, sound dinged. (torque222) *FAME: - HW - Perfect! Great Speed. (torque222) *FAME: - SW - Speed dinged, Sound dinged. (torque222) Aladdin I (Unl) *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Aladdin II (Checking on this) *C68K: - Good (torque222) *FAME: - Good (torque222) Aleste - Full Metal Fighter Ellinor (J) [!] *C68K: Crashes. *FAME: Crashes. Alex Kidd in the Enchanted Castle (U) [!] *C68K: - HW - Locks *C68K: - SW - Locks *FAME: - HW - Locks *FAME: - SW - Locks Alien 3 (JUE) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Locks (torque222) Alien Soldier (E) [!] *C68K: - HW - Graphical Mess (torque222) *C68K: - SW - Graphical Mess (torque222) *FAME: - HW - Perfect! WOW! (torque222) *FAME: - SW - Speed dinged, sound dinged. (torque222) Alien Storm (W) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *C68K: - SW - Not bad a little slower. (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Sound dinged, Speed more controlled. (torque222) Alisia Dragoon (U) [!] *C68K: - HW - Perfect *C68K: - SW - Good *FAME: - HW - Won't Start *FAME: - SW - Won't Start Altered Beast (UE) (REV02) [!] *C68K: - HW - WON'T LOAD *C68K: - SW - Won't load (torque222) *FAME: - HW - WON'T LOAD *C68K: - SW - Won't load (torque222) *Some games hang just at the splash 'SEGA' screen. Maybe someone could create a fix for this problem ;-) American Gladiators (U) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *C68K: - SW - A little slow. (torque222) *FAME: - HW - No Screen (torque222) *FAME: - SW - No Screen (torque222) Andre Agassi Tennis (U) (REV00) [!] *C68K: - Perfect (torque222) *FAME: - Perfect (torque222) Animaniacs (U) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *C68K: - SW - *FAME: - HW - Perfect (torque222) *FAME: - SW - Good a little slow. (torque222) Another World (E) *C68K: - Perfect! (perfeito! / Falcon Silva) *C68K: - SW - Good (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Good (torque222) Aq Renkan Awa (Unl) *C68K: - HW - Perfect (tirque222) *C68K: - SW - Perfect (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Locked and restart needed. (torque222) Aquatic Games - Starring James Pond, The (UE) [!] *C68K: - HW - Graphical Errors. (torque222) *C68K: - SW - *FAME: - HW - Very Fast but good. (torque222) *FAME: - SW - Regular speed, sound dinged. (torque222) Arcade Classics (U) [!] *C68K: - HW - Good (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Good (torque222) Arch Rivals (UE) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Won't Start (torque222) *FAME: - SW - Won't Start (torque222) Arcus Odyssey (U) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Very Good (torque222) Ariel - The Little Mermaid (UE) [!] *C68K: - HW - Very Good (torque222) *FAME: - SW - Very Good (torque222) Arnold Palmer Tournament Golf (UE) [!] *C68K: - HW - Some graphics missing (torque222) *FAME: - HW - Some graphics missing (torque222) *FAME: - SW - Must be sw (torque222) Arrow Flash (UE) [!] *C68K: - HW - Very Good! (torque222) *C68K: - SW - Too fast! (torque222) *FAME: - HW - Too fast! (torque222) *FAME: - SW - Too fast! (torque222) Art Alive! (W) [!] *C68K: - Good (torque222) *FAME: - Good (torque222) Art of Fighting (U) [!] *C68K: - HW - Locked (torque222) *C68K: - SW - Good a bit slow (torque222) *FAME: - HW - Locked (torque222) *FAME: - SW - Glitches, messed up but it runs! (torque222) Asterix and the Great Rescue (E) (M5) [c][!] *C68K: - Perfect (torque222) *C68K: - SW - Good (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Good invisible sometimes when hit. (torque222) Asterix and the Power of The Gods (E) (M4) [!] *C68K: - HW - Perfect (torque222) *C68K: - SW - Very Good (torque222) *FAME: - HW - Perfect (torque222) *FAME: - SW - Atomic Robo-Kid (U) [c][!] *C68K: - Perfect (torque222) *C68K: - Very Good (torque222) *FAME: - HW - Great Speed but enemie's weapons speed up and some graphical glitches. (torque222) *FAME: - SW - Perfect, Just a slight sound problem. (torque222) Atomic Runner (U) [!] *C68K: -Perfect *FAME: - ATP Tour Championship Tennis (U) [!] *C68K: - HW - Perfect - maybe a bit fast. (torque222) *C68K: - SW - a little slower But easier. (torque222) *FAME: - HW - Tremendious speed sits at one of the start *FAME: - HW - menu's for 35 seconds or so.(torque222) *FAME: - SW - Same as HW. (torque222) Awesome Possum Kicks Dr. Machino's Butt! (U) [!] *C68K: - HW - Perfect : SW Slower (torque222) *FAME: - HW - Perfect : SW Slower (torque222) AWS Pro Moves Soccer (U) [!] *C68K: - *FAME: - Ayrton Senna's Super Monaco GP II (U) [!] *C68K: - Work, with bugs in video (funciona com bugs no video / Falcon Silva) *C68K: - SW - Good (torque222) *FAME: - HW - Screen completely screwed up. But running ;-) (torque222) *FAME: - SW - Good (torque222) ==B== B.O.B (UE) (REV01) [!] *C68K: - HW - Perfect except inventory menu's cursor is missing, so you must memorize how to use it and it does become quite easy. (torque222) *C68K: - SW - Slower than normal but Menu's cursor is there. *FAME: - HW - Same as above : - SW - Same as above (torque222) Baby's Day Out (Beta 2) *C68K: - HW - Perfect : - SW - Slower *FAME: - HW - Perfect : - SW - Slower Back to the Future Part III (U) [!] *C68K: - HW - Too fast : - SW - Too fast (torque222) *FAME: - HW - Too fast : - SW - Too fast (torque222) *Note Could use dcgen or an older slow one to make this game more playable, I tried it on dcgen .35 and it was alittle too slow but a lot easier! Could also use an older Genesis plus version. Because There are a lot of slow Sega Genesis emulators for the dreamcast.(torque222) Bahamut Senki (J) [c][!] *C68K: - HW - Perfect - SW - Near Perfect (torque222) *FAME: - HW - Perfect - SW - Near Perfect (torque222) Ball Jacks (JE) [c][!] *C68K: - HW - Perfect - SW - Near Perfect (torque222) *FAME: - HW - Perfect - SW - Near Perfect (torque222) Balloon Boy (Unl) [f1] *C68K: - HW - 95% - SW - 90% (torque222) *FAME: - HW - Locked Restart needed. (torque222) *FAME: - SW - Locked Restart needed. (torque222) Ballz (UE) [!] *C68K: - HW - Won't Start - SW - Won't Start *FAME: - HW - Won't Start - SW - Won't Start Barbie Super Model (U) [!] *C68K: - HW - Problem - SW - Problem *FAME: - HW - Problem - SW - Problem *Note special problem cannot pick up Icons or hit cars. Barbie Vacation Adventure (Beta) *C68K: - HW - 100% but text captions cannot be seen. (torque222) *C68K: - SW - 95% speed / sound (torque222) *FAME: - HW - 100% but text captions cannot be seen. (torque222) *FAME: - SW - 97% speed / sound (torque222) Bare Knuckle 3 (J) [!] *C68K: - HW - Perfect! (torque222) *C68K: - SW - 95% (torque222) *FAME: - HW - Perfect! (torque222) *FAME: - SW - 97% (torque222) Barkley Shut Up and Jam! (UE) [!] *C68K: - HW - Too Fast & graphic errors (torque222) *C68K: - SW - Good Very Playable (torque222) *FAME: - HW - Too Fast (torque222) *FAME: - SW - Good Very Playable (torque222) Barkley Shut Up and Jam! 2 (U) [!] *C68K: - HW - Very Fast & graphical errors (torque222) *C68K: - SW - Good Very Playable (torque222) *FAME: - HW - Very Fast & graphical errors (torque222) *FAME: - SW - 98% very playable Barney's Hide & Seek Game (U) [!] *C68K: - HW - 98% *C68K: - SW - 95% *FAME: - HW - 99% *FAME: - SW - 96% Barver Battle Saga - The Space Fighter (Ch) *C68K: - HW - Video Problems (torque222) *C68K: - SW - Very Good 98% sound (torque222) *FAME: - HW - Locked Up (torque222) *FAME: - SW - Locked Up Restart Needed (torque222) *Special Note avoid FAME on this game because a very loud noise came from the Dreamcast before it locked. Bass Masters Classic Pro Edition (U) [!] *C68K: - HW - Locked Up Restart Needed (torque222) *C68K: - SW - Locked Up Restart Needed (torque222) *FAME: - HW - Locked Up Restart Needed (torque222) *FAME: - SW - Locked Up Restart Needed (torque222) Bass Masters Classics (U) [!] *C68K: - HW - Good, must be set to USA. (torque222) *C68K: - SW - Good *FAME: - HR - Good *FAME: - SW - Good Batman (UE) [!] *C68K: - Work, with bugs in video (funciona com bugs de video) *FAME: - Batman - Revenge of the Joker (U) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Batman Forever (F) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Batman Returns (U) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Battle Golfer Yui (J) [c][!] *C68K: - HW - Perfect but sound problem (torque222) *C68K: - SW - Good but sound problem (torque222) *FAME: - HW - No text stuck *FAME: - SW - No text stuck Battle Mania - Dai Gin Jou (J) [c][!] *C68K: - *FAME: - Battle Squadron (U) [!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Battlemaster (U) [c][!] *C68K: - *FAME: - Battletech (U) [!] *C68K: - *FAME: - Battletoads (W) [!] *C68K: Perfect! *FAME: - Battletoads and Double Dragon (U) [c][!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Beast Wrestler (U) [!] *C68K: - *FAME: - Beauty and the Beast - Belle's Quest (U) [!] *C68K: - *FAME: - Beauty and the Beast - Roar of the Beast (U) [!] *C68K: - *FAME: - Beavis and Butt-head (U) [!] *C68K: - Perfect *FAME: - Same. Berenstain Bears', The - Camping Adventure (U) [!] *C68K: - *FAME: - Best of the Best - Championship Karate (U) [c][!] *C68K: - Perfect! (perfeito! / Falcon Silva) *FAME: - Beyond Oasis (U) [!] *C68K: - Runs too fast *FAME: - Runs too fast Beyond Oasis (U) [f1] *C68K: HW - Good *FAME: - Beyond Zero Tolerance (Beta) *C68K: - *FAME: - Bible Adventures (Unl) [!] *C68K: - *FAME: - Bill Walsh College Football '95 (U) [!] *C68K: - *FAME: - Bill Walsh College Football (UE) [c][!] *C68K: - *FAME: - Bimini Run (U) (REV02) [!] *C68K: - *FAME: - Bio-Hazard Battle (UE) [!] *C68K: - *FAME: - Bishoujo Senshi Sailor Moon (J) [!] *C68K: - *FAME: - Blades of Vengeance (UE) [!] *C68K: -Perfect *FAME: - Blaster Master 2 (U) [c][!] *C68K: - *FAME: - Block Out (W) (REV01) [!] *C68K: - *FAME: - Blockbuster World Video Game Championship II (U) *C68K: - *FAME: - Blood Shot (E) (M4) [!] *C68K: - *FAME: - Blue Almanac (J) [!] *C68K: - *FAME: - Body Count (E) (M5) [!] *C68K: - *FAME: - Bonanza Bros. (U) [!] *C68K: - *FAME: - Bonkers (UE) [!] *C68K: - *FAME: - Boogerman (U) [!] *C68K: - *FAME: - Boxing Legends of the Ring (U) [!] *C68K: - *FAME: - Bram Stoker's Dracula (U) [!] *C68K: - Work, with bugs in video (funciona mas com bugs de video / Falcon Silva) *FAME: - Brett Hull Hockey '95 (U) [!] *C68K: - *FAME: - Brian Lara Cricket (E) [c][!] *C68K: - *FAME: - Brian Lara Cricket 96 (E) [c][!] *C68K: - *FAME: - Brutal - Paws of Fury (E) [!] *C68K: - Works, with bugs and fast game (funciona com bugs de video e velocidade rápida) *FAME: - Bubba N Stix (U) [!] *C68K: - *FAME: - Bubble and Squeak (U) [!] *C68K: - *FAME: - Bubsy II (UE) [!] *C68K: - *FAME: - Bubsy in Claws Encounters of the Furred Kind (UE) [!] *C68K: - *FAME: - Buck Rogers - Countdown to Doomsday (UE) [!] *C68K: - *FAME: - Budokan - The Martial Spirit (U) [c][!] *C68K: - *FAME: - Bug's Life, A (Unl) [!] *C68K: - *FAME: - Bugs Bunny in Double Trouble (U) [!] *C68K: - *FAME: - Bulls vs Blazers and the NBA Playoffs (UE) [!] *C68K: - *FAME: - Bulls vs Lakers and the NBA Playoffs (UE) [!] *C68K: - *FAME: - Burning Force (U) [!] *C68K: - *FAME: - ==C== Cadash (JU) [c][!] *C68K: - *FAME: - Caesars Palace (U) [!] *C68K: - *FAME: - Cal Ripken Jr. Baseball (U) [c][!] *C68K: - *FAME: - Caliber Fifty (U) [!] *C68K: - *FAME: - California Games (UE) [!] *C68K: - *FAME: - Cannon Fodder (E) [!] *C68K: - *FAME: - Captain America and the Avengers (U) [!] *C68K: - Works well but has low-pitched voices *FAME: - Captain Planet and the Planeteers (E) [!] *C68K: - *FAME: - Castle of Illusion Starring Mickey Mouse (UE) [!] *C68K: - *FAME: - Castlevania - Bloodlines (U) [!] *C68K: - Perfect, except text doesn't appear in intro. *FAME: - Perfect, but crashes if left to run in demo mode. Centurion - Defender of Rome (UE) [!] *C68K: - *FAME: - Chakan - The Forever Man (UE) [!] *C68K: - *FAME: - Chameleon Kid (J) [!] *C68K: -Perfect *FAME: - Champions World Class Soccer (W) (M4) [!] *C68K: - *FAME: - Championship Bowling (U) [!] *C68K: - *FAME: - Championship Pool (U) [!] *C68K: - *FAME: - Championship Pro-Am (U) [c][!] *C68K: - *FAME: - Chaoji Dafuweng (Unl) [!] *C68K: - *FAME: - Chase HQ II (U) [!] *C68K: - *FAME: - Chavez II (U) [!] *C68K: - *FAME: - Cheese Cat-Astrophe Starring Speedy Gonzales (E) (M4) [!] *C68K: - *FAME: - Chess (Unl) [!] *C68K: - *FAME: - Chester Cheetah (U) [c][!] *C68K: - *FAME: - Chester Cheetah 2 - Wild Wild Quest (U) [!] *C68K: - *FAME: - Chi Chi's Pro Challenge (U) [!] *C68K: - *FAME: - Chibi Maruko-Chan - Wakuwaku Shopping (J) [c][!] *C68K: - *FAME: - Chiki Chiki Boys (UE) [!] *C68K: - Perfect, but music *seems* a tad slow. *FAME: - Chinese Chess (Unl) *C68K: - *FAME: - Chou Yakyuu Miracle Nine (J) [!] *C68K: - *FAME: - Chuck Rock II - Son of Chuck (U) [!] *C68K: - Perfect. *FAME: - Same. Chuck Rock (U) [c][!] *C68K: - *FAME: - Chuck's Excellent Art Tool Animator (U) *C68K: - *FAME: - Classic Collection (UE) [!] *C68K: - *FAME: - Clay Fighter (U) [!] *C68K: - *FAME: - Cliffhanger (U) [c][!] *C68K: - *FAME: - Clue (U) [!] *C68K: - *FAME: - Coach K College Basketball (U) [!] *C68K: - *FAME: - College Football USA 96 (U) [!] *C68K: - *FAME: - College Football USA 97 - The Road to New Orleans (U) [!] *C68K: - *FAME: - College Football's National Championship (U) [!] *C68K: - *FAME: - College Football's National Championship II (U) [!] *C68K: - *FAME: - College Slam (U) [!] *C68K: - *FAME: - Columns (W) (REV01) [!] *C68K: Very good! *FAME: - Columns III - Revenge of Columns (U) [!] *C68K: - Perfect. *FAME: - Couldn't get it to work. (rom W/ intro) Combat Aces (Beta) *C68K: - *FAME: - Combat Cars (UE) [!] *C68K: - *FAME: - Comix Zone (U) [!] *C68K: - Working but glitches and slow. *FAME: - Title screen gfx glitch, Sound is perfect. Command & Conquer (Beta) *C68K: - *FAME: - Commandos (R) *C68K: - *FAME: - Congo - The Game (Beta) *C68K: - *FAME: - Conquering the World III (Ch-Simple) *C68K: - *FAME: - Contra - Hard Corps (U) [!] *C68K: - Working but a tad slow. *FAME: - This CPU runs perfect Cool Spot (U) [!] *C68K: -Perfect *FAME: - Cosmic Spacehead (E) (M4) [c][!] *C68K: - *FAME: - Crack Down (U) [!] *C68K: - *FAME: - Crayon Shin-Chan - Arashi o Yobu Sono Ko (J) [!] *C68K: - *FAME: - Crue Ball (UE) [!] *C68K: - *FAME: - Crusader of Centy (U) [!] *C68K: - Good, inventory menu keeps it from being 100% *FAME: - Freezes at SEGA logo. Crying (J) *C68K: Works, but player graphics aren't displaying. *FAME: Sound is awfully distorted. Crystal's Pony Tale (U) [!] *C68K: - *FAME: - Curse (J) [!] *C68K: - *FAME: - Cutthroat Island (UE) [!] *C68K: - *FAME: - Cuty Suzuki no Ringside Angel (J) [!] *C68K: - *FAME: - Cyber-Cop (U) [c][!] *C68K: - *FAME: - CyberBall (W) [!] *C68K: - *FAME: - Cyborg Justice (W) [!] *C68K: - *FAME: - ==D== D&D - Warriors of the Eternal Sun (UE) [!] *C68K: - *FAME: - Daffy Duck in Hollywood (E) (M5) [!] *C68K: - *FAME: - Dahna - Megami Tanjou (J) [!] *C68K: - *FAME: - Dangerous Seed (J) [!] *C68K: - *FAME: - Darius II (J) [c][!] *C68K: - *FAME: - Dark Castle (UE) [!] *C68K: - *FAME: - Darwin 4081 (J) [!] *C68K: - *FAME: - Dashin' Desperadoes (U) [!] *C68K: - *FAME: - David Crane's Amazing Tennis (U) [!] *C68K: - *FAME: - David Robinson's Supreme Court (U) [!] *C68K: - *FAME: - Davis Cup World Tour Tennis (UE) [!] *C68K: - *FAME: - Davis Cup World Tour Tennis 2 (Beta 2) *C68K: - *FAME: - Daze Before Christmas, The (E) [!] *C68K: - *FAME: - Deadly Moves (U) [!] *C68K: - *FAME: - Death and Return of Superman, The (U) [!] *C68K: - *FAME: - Death Duel (U) [!] *C68K: - *FAME: - Decap Attack (UE) [!] *C68K: - *FAME: - Deer Hunter (R) *C68K: - *FAME: - Demolition Man (UE) [!] *C68K: - *FAME: - Desert Demolition (UE) [!] *C68K: - *FAME: - Desert Strike - Return to the Gulf (UE) [!] *C68K: - *FAME: - Devil's Course 3-D Golf (J) [!] *C68K: - *FAME: - Devilish - The Next Possession (U) [c][!] *C68K: - *FAME: - Devilish Mahjong Tower (Unl) *C68K: - *FAME: - Dial Q o Mawase! (Unl) *C68K: - *FAME: - Dick Tracy (W) [c][!] *C68K: - *FAME: - Dick Vitale's Awesome Baby! College Hoops (U) [!] *C68K: - *FAME: - Dino Dini's Soccer (E) *C68K: - *FAME: - Dino Land (U) [!] *C68K: - *FAME: - Dinosaurs for Hire (U) [!] *C68K: - *FAME: - Disney's Aladdin (U) [!] *C68K: - *FAME: - Divine Sealing (Unl) [!] *C68K: - *FAME: - DJ Boy (U) [!] *C68K: - *FAME: - Doki Doki Penguin Land MD (SN) (J) [!] *C68K: - *FAME: - Domino (Unl) *C68K: - *FAME: - Dominus (Beta) *C68K: - *FAME: - Donald in Maui Mallard (E) [!] *C68K: - Perfect. *FAME: - Doom Troopers - The Mutant Chronicles (U) [c][!] *C68K: - *FAME: - Doraemon - Yume Dorobouto 7 Nin No Gozansu (J) [!] *C68K: - *FAME: - Double Clutch (E) [c][!] *C68K: - *FAME: - Double Dragon (U) [!] *C68K: -Perfect *FAME: - Double Dragon 2 - The Revenge (J) [!] *C68K: - *FAME: - Double Dragon 3 - The Rosetta Stone (UE) [!] *C68K: - *FAME: - Double Dragon V - The Shadow Falls (U) [!] *C68K: - *FAME: - Double Dribble - The Playoff Edition (U) [!] *C68K: - *FAME: - Dr. Robotnik's Mean Bean Machine (U) [!] *C68K: -Perfect *FAME: - Dragon - The Bruce Lee Story (U) [!] *C68K: - *FAME: - Dragon Ball Z - L'Appel du Destin (F) [!] *C68K: - Works well, but has split-screen issues. *FAME: - Same. Dragon Slayer - The Legend of Heroes (J) [!] *C68K: - *FAME: - Dragon Slayer II - The Legend of Heroes (J) [!] *C68K: - *FAME: - Dragon's Eye - Shanghai 3 (J) [!] *C68K: - *FAME: - Dragon's Fury (UE) [!] *C68K: -Slow framerate, graphical glitches *FAME: -same Dragon's Revenge (UE) [!] *C68K: -As in Dragon's Fury, slowdown, gfx glitches *FAME: -same Duke Nukem 3D (B) [!] *C68K: - *FAME: - Dune - The Battle for Arrakis (U) [!] *C68K: - *FAME: - Dyna Brothers (J) (REV01) *C68K: - *FAME: - Dyna Brothers 2 (J) [!] *C68K: - *FAME: - Dynamite Duke (W) [!] *C68K: - *FAME: - Dynamite Headdy (UE) [c][!] *C68K: - Freezes before game begins. *FAME: - Same. -try a different ROM, mine works fine. ==E== Earnest Evans (U) [!] *C68K: - *FAME: - Earth Defend, The (Unl) [!] *C68K: - *FAME: - Earthworm Jim (U) [!] *C68K: Perfect, but lower-pitched voices. *FAME: Same. Earthworm Jim 2 (U) [!] *C68K: -Perfect *FAME: - ECCO - The Tides of Time (U) [!] *C68K: - Perfect, but lower-pitched voices. (can't read dolphin dialogue) *FAME: - Same. ECCO Jr. (U) (REV01) [!] *C68K: - *FAME: - ECCO The Dolphin (UE) [!] *C68K: - slowdown, can't read dolphin dialogue *FAME: -same El Viento (U) [!] *C68K: - *FAME: - Elemental Master (U) [!] *C68K: - *FAME: - Elf Wor (Unl) *C68K: - *FAME: - Eliminate Down (J) [!] *C68K: - *FAME: - Escape From Mars Starring Taz (U) [!] *C68K: - *FAME: - ESPN Baseball Tonight (U) [!] *C68K: - *FAME: - ESPN National Hockey Night (U) [c][!] *C68K: - *FAME: - ESPN SpeedWorld (U) [c][!] *C68K: - *FAME: - ESPN Sunday Night NFL (U) [!] *C68K: - *FAME: - ESWAT Cyber Police - City Under Siege (U) [!] *C68K: - *FAME: - Eternal Champions (U) [!] *C68K: - *FAME: - European Club Soccer (E) [!] *C68K: - *FAME: - Evander Holyfield's Real Deal Boxing (JU) [!] *C68K: - *FAME: - Ex-Mutants (U) [!] *C68K: - *FAME: - Exile (U) [!] *C68K: - *FAME: - Exo-Squad (U) [!] *C68K: - *FAME: - Exodus (Unl) [!] *C68K: - *FAME: - ==F== F-117 Night Storm (UE) [!] *C68K: - *FAME: - F-15 Strike Eagle II (U) [!] *C68K: - *FAME: - F-22 Interceptor (U) (Jun 1992) [c][!] *C68K: - *FAME: - F1 Circus MD (J) [!] *C68K: - *FAME: - F1 Grand Prix - Nakajima Satoru (J) [!] *C68K: - *FAME: - F1 Super License - Nakajima Satoru (J) [!] *C68K: - *FAME: - F1 World Championship (U) [!] *C68K: - *FAME: - F1 World Championship Edition (E) [!] *C68K: - *FAME: - Faery Tale Adventure, The (UE) [!] *C68K: - *FAME: - Family Feud (U) [!] *C68K: - *FAME: - Fantasia (JU) (REV01) [!] *C68K: - *FAME: - Fantastic Dizzy (UE) (M5) [c][!] *C68K: - *FAME: - Fastest 1 (J) [!] *C68K: - *FAME: - Fatal Fury (U) [!] *C68K: - *FAME: - Fatal Fury 2 (U) [c][!] *C68K: - *FAME: - Fatal Labyrinth (JU) [!] *C68K: - *FAME: - Fatal Rewind (UE) [!] *C68K: - *FAME: - Fengshen Yingjiechuan (Ch) *C68K: - *FAME: - Ferias Frustradas do Pica-Pau (B) [!] *C68K: - *FAME: - Ferrari Grand Prix Challenge (U) [!] *C68K: - *FAME: - Fido Dido (Unl) *C68K: - *FAME: - FIFA International Soccer (UE) (M4) [!] *C68K: - *FAME: - FIFA Soccer 2000 Gold Edition (Unl) (M6) [!] *C68K: - *FAME: - FIFA Soccer 95 (UE) [!] *C68K: - *FAME: - FIFA Soccer 96 (UE) (M6) [!] *C68K: - *FAME: - FIFA Soccer 97 Gold Edition (UE) (M6) [!] *C68K: - *FAME: - FIFA Soccer 98 - Road to the World Cup (E) (M5) [!] *C68K: - *FAME: - FIFA Soccer 99 (R) [!] *C68K: - *FAME: - Fighting Masters (U) [!] *C68K: - *FAME: - Final Fantasy (R) *C68K: - *FAME: - Final Zone (JU) [!] *C68K: - *FAME: - Fire Mustang (J) [c][!] *C68K: - *FAME: - Fire Pro Wrestling Gaiden (J) [c][!] *C68K: - *FAME: - Fire Shark (U) [!] *C68K: - *FAME: - Flashback - The Quest for Identity (U) [!] *C68K: - *FAME: - Flicky (UE) [!] *C68K: - *FAME: - Flintstones, The (U) [c][!] *C68K: - Perfect. *FAME: - Same. Foreman For Real (W) [!] *C68K: - *FAME: - Forgotten Worlds (W) (REV01) [!] *C68K: - *FAME: - Frank Thomas Big Hurt Baseball (UE) [!] *C68K: - *FAME: - Frogger (U) [!] *C68K: - *FAME: - Fun Car Rally (Unl) *C68K: - *FAME: - Fun-N-Games (U) [c][!] *C68K: - *FAME: - Funny World (Unl) [f1] *C68K: - *FAME: - Fushigi no Umi no Nadia (J) [c][!] *C68K: - *FAME: - Futbol Argentino 98 - Pasion de Multitudes (Unl) *C68K: - *FAME: - ==G== G-LOC Air Battle (W) [c][!] *C68K: - *FAME: - Gadget Twins, The (U) [!] *C68K: - *FAME: - Gaiares (JU) [!] *C68K: Very good but explosion sounds are distorted. *FAME: - Gain Ground (UE) [c][!] *C68K: - *FAME: - Galaxy Force II (W) (REV01) [!] *C68K: - *FAME: - Gambler Jiko Chuushinha - Katayama Masayuki no Mahjong Doujou (J) [!] *C68K: - *FAME: - Game no Kanzume Otokuyou (J) [!] *C68K: - *FAME: - Garfield - Caught in the Act (UE) [!] *C68K: 100% Perfect. *FAME: 100% Perfect. Gargoyles (U) [!] *C68K: - *FAME: - Gauntlet 4 (UE) (Sep 1993) *C68K: - *FAME: - GemFire (U) [!] *C68K: - *FAME: - General Chaos (UE) [!] *C68K: - *FAME: - Generations Lost (UE) [!] *C68K: - *FAME: - Genghis Khan II - Clan of the Gray Wolf (U) [!] *C68K: - *FAME: - George Foreman's KO Boxing (U) [!] *C68K: - *FAME: - Ghost Hunter (Unl) *C68K: - *FAME: - Ghostbusters (W) (REV01) [!] *C68K: - *FAME: - Ghouls 'N Ghosts (UE) (REV02) [!] *C68K: - Works but strange colors and fast music *FAME: - Works but fast music. Gley Lancer (J) [!] *C68K: - *FAME: - Gods (U) [!] *C68K: - *FAME: - Golden Axe (W) (REV01) [!] *C68K: - Perfect. *FAME: - Same. Golden Axe II (W) [!] *C68K: - Perfect. *FAME: - Works but music is insanely fast and game is insanely slow. Golden Axe III (J) [!] *C68K: Graphical errors *FAME: Hangs. Golden Axe III (J)[p1] [!] *C68K: HW - Perfect. *FAME: Hangs. Goofy's Hysterical History Tour (U) [!] *C68K: - *FAME: - Granada (JU) (REV01) [!] *C68K: - *FAME: - Great Circus Mystery, The - Starring Mickey & Minnie (U) [!] *C68K: - *FAME: - Great Waldo Search, The (U) [!] *C68K: - *FAME: - Greatest Heavyweights of the Ring (U) [!] *C68K: - *FAME: - Greendog - The Beached Surfer Dude (UE) [!] *C68K: -Perfect *FAME: - GRIND Stormer (U) [!] *C68K: - *FAME: - Growl (U) [!] *C68K: - *FAME: - Gunship (E) [c][!] *C68K: - *FAME: - Gunstar Heroes (U) [!] *C68K: Freezes before in-game. *FAME: Works well W/ minor GFX errors and fast music (gfx glitches in beginning of airship stage) Gynoug (J) [!] *C68K: Perfect. *FAME: Perfect. ==H== Hard Drivin' (W) [!] *C68K: - *FAME: - HardBall '94 (UE) [!] *C68K: - *FAME: - HardBall '95 (U) [!] *C68K: - *FAME: - HardBall III (U) [!] *C68K: - *FAME: - HardBall! (U) [!] *C68K: - *FAME: - Harry Potter (R) *C68K: - *FAME: - Haunting Starring Polterguy (UE) [!] *C68K: - *FAME: - Head-On Soccer (U) (M5) [!] *C68K: - *FAME: - Heavy Nova (U) [!] *C68K: - *FAME: - Heavy Unit (J) [!] *C68K: - *FAME: - Hellfire (U) [!] *C68K: - *FAME: - Hellfire (J) [!] *C68K: - *FAME: - Hercules 2 (Unl) *C68K: - *FAME: - Herzog Zwei (UE) [!] *C68K: - *FAME: - High School Soccer - Kunio Kun (J) [!] *C68K: - *FAME: - High Seas Havoc (U) [!] *C68K: - *FAME: - Hit The Ice (U) [c][!] *C68K: - *FAME: - Hokuto no Ken (J) [!] *C68K: - *FAME: - Home Alone (U) [!] *C68K: - *FAME: - Home Alone 2 - Lost in New York (U) [!] *C68K: - *FAME: - Honoo no Toukyuuji Dodge Danpei (J) [!] *C68K: - *FAME: - Hook (U) [c][!] *C68K: - *FAME: - Humans, The (U) [!] *C68K: - *FAME: - Hurricanes (E) [!] *C68K: - *FAME: - Hybrid Front, The (J) [!] *C68K: - *FAME: - Hyokkori Hyoutanjima (J) [c][!] *C68K: - *FAME: - Hyper Marbles (SN) (J) [!] *C68K: - *FAME: - ==I== Ichidant R (J) [!] *C68K: - *FAME: - IMG International Tour Tennis (UE) [!] *C68K: - *FAME: - Immortal, The (UE) [!] *C68K: - *FAME: - Incredible Crash Dummies, The (UE) [c][!] *C68K: - *FAME: - Incredible Hulk, The (UE) [!] *C68K: - *FAME: - Indiana Jones and the Last Crusade (U) [c][!] *C68K: - *FAME: - Insector X (U) [!] *C68K: - *FAME: - International Rugby (E) [c][!] *C68K: - *FAME: - International Superstar Soccer Deluxe (E) [!] *C68K: - *FAME: - Iraq War 2003 (Unl) *C68K: - *FAME: - Ishido - The Way of the Stones (U) [c][!] *C68K: - *FAME: - It Came From The Desert (Beta) *C68K: - *FAME: - Itchy and Scratchy Game, The (Beta) *C68K: - *FAME: - Izzy's Quest for the Olympic Rings (UE) [!] *C68K: - *FAME: - ==J== J. League Pro Striker (J) (REV03) [c][!] *C68K: - *FAME: - J. League Pro Striker - Perfect Edition (J) [c][!] *C68K: - *FAME: - J. League Pro Striker 2 (J) [!] *C68K: - *FAME: - J. League Pro Striker Final Stage (J) [c][!] *C68K: - *FAME: - Jack Nicklaus' Power Challenge Golf (UE) [!] *C68K: - *FAME: - James Bond 007 - The Duel (W) *C68K: - *FAME: - James Buster Douglas Knock Out Boxing (UE) [c][!] *C68K: - *FAME: - James Pond - Underwater Agent (UE) [!] *C68K: - *FAME: - James Pond 3 - Operation Starfish (UE) [!] *C68K: - *FAME: - James Pond II - Codename RoboCod (UE) [!] *C68K: - *FAME: - Jammit (U) [!] *C68K: - *FAME: - Janou Touryumon (J) [!] *C68K: - *FAME: - Jantei Monogatari (J) [!] *C68K: - *FAME: - Jelly Boy (Beta) *C68K: - *FAME: - Jennifer Capriati Tennis (U) [!] *C68K: - *FAME: - Jeopardy! (U) [c][!] *C68K: - *FAME: - Jeopardy! Deluxe (U) [c][!] *C68K: - *FAME: - Jeopardy! Sports Edition (U) [!] *C68K: - *FAME: - Jerry Glanville's Pigskin Footbrawl (U) [!] *C68K: - *FAME: - Jewel Master (UE) [!] *C68K: - *FAME: - Jim Power - The Arcade Game (Beta) *C68K: - *FAME: - Jimmy White's Whirlwind Snooker (E) [c][!] *C68K: - *FAME: - Joe & Mac Caveman Ninja (U) [!] *C68K: - *FAME: - Joe Montana Football (JU) [!] *C68K: - *FAME: - Joe Montana Sports Talk Football (UE) [!] *C68K: - *FAME: - Joe Montana Sports Talk Football 2 (W) (REV01) [!] *C68K: - *FAME: - John Madden Football '92 (UE) [!] *C68K: - *FAME: - John Madden Football '93 (UE) [c][!] *C68K: - *FAME: - John Madden Football '93 - Championship Edition (U) [!] *C68K: - *FAME: - John Madden Football (UE) [!] *C68K: - *FAME: - John Madden NFL 94 (UE) [c][!] *C68K: - *FAME: - Jordan vs Bird - Super One-on-One (UE) (REV01) [!] *C68K: - *FAME: - Joshua & the Battle of Jericho (Unl) [!] *C68K: - *FAME: - Judge Dredd - The Movie (W) [!] *C68K: - *FAME: - Junction (JU) [!] *C68K: - *FAME: - Jungle Book, The (U) [!] *C68K: - *FAME: - Jungle Strike (UE) [!] *C68K: - *FAME: - Junkers High (Beta) *C68K: - *FAME: - Jurassic Park (U) [!] *C68K: - *FAME: - Jurassic Park - Rampage Edition (UE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Jurassic Park 2 - The Lost World (F) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Justice League Task Force (W) [!] *C68K: - *FAME: - Juu-Ou-Ki (J) (REV01) [!] *C68K: - *FAME: - ==K== Ka-Ge-Ki - Fists of Steel (U) [!] *C68K: - *FAME: - Kawasaki Superbike Challenge (UE) [!] *C68K: - *FAME: - Kick Off 3 - European Challenge (E) [!] *C68K: - *FAME: - Kid Chameleon (UE) [!] *C68K: - Perfect but lower-pitched voices. *FAME: - Same. King Colossus (J) [T+Eng_M.I.J.E.T.] *C68K: - *FAME: - King of Fighters '98, The (Unl) [!] *C68K: - Bug in video (bugs de video / Falcon Silva) *FAME: - King of the Monsters (E) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - King of the Monsters 2 (U) [!] *C68K: - *FAME: - King Salmon - The Big Catch (U) [c][!] *C68K: - *FAME: - King's Bounty (UE) [!] *C68K: - *FAME: - Kishi Densetsu (J) [T+Eng20%_Gaijin_Productions] *C68K: - *FAME: - Klax (UE) [!] *C68K: - Perfect. *FAME: - Same. Krusty's Super Funhouse (UE) (REV01) [!] *C68K: - *FAME: - Kyuukai Douchuuki (J) [c][!] *C68K: - *FAME: - ==L== Labyrinth of Death (SN) (J) [!] *C68K: - *FAME: - Lakers vs Celtics and the NBA Playoffs (UE) [!] *C68K: - *FAME: - Landstalker - The Treasures of King Nole (U) [!] *C68K: - HW - Backgrounds glitchy, in-game text invisible *C68K: - SW - Runs without glitches, but slowly. Playable though. *FAME: - Runs too fast and freezes at start of intro sequence. Langrisser II (J) (REV01) [T+Eng100%_HiryuuHonyaku&NoPrgress] *C68K: - *FAME: - Last Action Hero (U) [!] *C68K: - *FAME: - Last Battle (UE) [!] *C68K: - *FAME: - Lawnmower Man, The (UE) [!] *C68K: - *FAME: - Legend of Galahad, The (UE) [!] *C68K: - *FAME: - Lemmings (JU) (REV01) [!] *C68K: - *FAME: - Lemmings 2 - The Tribes (U) [!] *C68K: - *FAME: - Lethal Enforcers (E) [!] *C68K: - Audio bug (bug's de audio / Falcon Silva) *FAME: - Lethal Enforcers II - Gun Fighters (E) [!] *C68K: - Audio bug (bug's de audio / Falcon Silva) *FAME: - LHX Attack Chopper (UE) [!] *C68K: - *FAME: - Liberty or Death (U) [!] *C68K: - *FAME: - Light Crusader (E) (M4) [!] *C68K: - *FAME: - Link Dragon (Unl) *C68K: - *FAME: - Lion King 3 (Unl) *C68K: - *FAME: - Lion King II, The (Unl) [!] *C68K: - *FAME: - Lion King, The (W) [!] *C68K: - Not load (Não carrega / Falcon Silva) *FAME: - Lord Monarch (J) [!] *C68K: - *FAME: - Lost Vikings, The (U) [!] *C68K: - *FAME: - Lotus II RECS (UE) [!] *C68K: - *FAME: - Lotus Turbo Challenge (UE) [!] *C68K: - *FAME: - ==M== M-1 Abrams Battle Tank (UE) (REV01) [!] *C68K: - *FAME: - M.U.S.H.A (U) [!] *C68K: - *FAME: - Madden NFL 95 (UE) [!] *C68K: - *FAME: - Madden NFL 96 (UE) [!] *C68K: - Not Load (Não carrega / Falcon Silva) *FAME: - Madden NFL 97 (UE) [!] *C68K: - *FAME: - Madden NFL 98 (U) [c][!] *C68K: - *FAME: - Madou Monogatari I (J) [!] *C68K: - *FAME: - Magic Girl (Unl) [!] *C68K: - *FAME: - Magic School Bus, The (U) [!] *C68K: - *FAME: - Magical Taruruuto-Kun (J) [!] *C68K: - *FAME: - Mahjong Cop Ryuu - Shiro Ookami no Yabou (J) [!] *C68K: - *FAME: - Mahjong Lover (Unl) [!] *C68K: - *FAME: - Mamono Hunter Yohko - Makai Kara no Tenkosei (J) [!] *C68K: - *FAME: - Man Overboard! - S.S. Lucifer (E) [c][!] *C68K: - *FAME: - Marble Madness (UE) [!] *C68K: - *FAME: - Mario Andretti Racing (UE) [!] *C68K: - Bug's in Video (Bug's de video / Falcon Silva) *FAME: - Mario Lemieux Hockey (UE) [!] *C68K: - *FAME: - Marko's Magic Football (E) (M4) [!] *C68K: - *FAME: - Marsupilami (U) (M5) [!] *C68K: - *FAME: - Marvel Land (U) [!] *C68K: - *FAME: - Mary Shelley's Frankenstein (U) [!] *C68K: - *FAME: - Master of Monsters (U) [!] *C68K: - *FAME: - Master of Weapon (J) [!] *C68K: - *FAME: - Maten Densetsu (J) [!] *C68K: - *FAME: - Math Blaster - Episode 1 (U) [!] *C68K: - *FAME: - Mazin Saga (U) [!] *C68K: - *FAME: - McDonald's Treasure Land Adventure (U) [!] *C68K: - *FAME: - Mega Anser (J) (REV01) [!] *C68K: - *FAME: - Mega Bomberman (UE) [!] *C68K: Perfect. *FAME: Crashes in Round 1. Mega Q - The Party Quiz Game (J) [!] *C68K: - *FAME: - Mega SWIV (E) *C68K: - *FAME: - Mega Turrican (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Megaman - The Wily Wars (E) *C68K: - Perfect. *FAME: - Hangs. Megapanel (J) [c][!] *C68K: - *FAME: - Menacer 6-in-1 Game Pack (UE) [!] *C68K: - *FAME: - Mercs (W) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Metal Fangs (J) [c][!] *C68K: - *FAME: - Michael Jackson's Moonwalker (W) (REV01) [!] *C68K: - Perfect *FAME: - Same. Mick & Mack as the Global Gladiators (U) [!] *C68K: - *FAME: - Mickey Mania - Timeless Adventures of Mickey Mouse (E) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mickey Mouse - Castle of Illusion (U) *C68K: - Audio bug (bug de audio / Falcon Silva) *FAME: - Mickey Mouse - Fantasia (U) *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mickey Mouse - Greate Circus (U) *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mickey Mouse - World of Illusion (E) *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mickey's Ultimate Challenge (U) [!] *C68K: - *FAME: - Micro Machines (UE) [c][!] *C68K: - Works perfect. *FAME: - Works perfect. Micro Machines - Turbo Tournament '96 (V1.1) (E) *C68K: - Works perfect. *FAME: - Mode selection screen does black, but can still select mode. Micro Machines 2 - Turbo Tournament (E) [c][!] *C68K: - Works perfect. *FAME: - Character selection screen goes black, but can still choose your character. Micro Machines Military - It's a Blast! (E) (J-Cart) [c][!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Midnight Resistance (U) [!] *C68K: - *FAME: - Mig-29 Fighter Pilot (U) [!] *C68K: - *FAME: - Might and Magic - Gates to Another World (UE) (REV01) [!] *C68K: - *FAME: - Might and Magic III - Isles of Terra (U) [h1C] *C68K: - *FAME: - Mighty Morphin Power Rangers (E) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mighty Morphin Power Rangers - The Movie (E) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mike Ditka Power Football (U) [!] *C68K: - *FAME: - Minnesota Fats Pool Legend (U) [!] *C68K: - *FAME: - Miracle Piano Teaching System (U) [!] *C68K: - *FAME: - Misadventures of Flink, The (E) [!] *C68K: - *FAME: - MK 5 - Mortal Combat - SubZero (Unl) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - MLBPA Baseball (U) [!] *C68K: - *FAME: - MLBPA Sports Talk Baseball (U) [!] *C68K: - *FAME: - Monopoly (U) [c][!] *C68K: - Perfect. *FAME: - Works but extremely fast gameplay and slow music. Monster World IV (J) [T+Eng1.02_DeJap+Demiforce] *C68K: - *FAME: - Mortal Kombat (UE) (REV01) [c][!] *C68K: - almost perfect, small bug's in video (Quase perfeito perquenos bug's no video / Falcon Silva) *FAME: - Mortal Kombat 3 (U) [!] *C68K: - almost perfect, audio noise (quase perfeito audio chiado / Falcon Silva *FAME: - Mortal Kombat II (W) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Mr. Nutz (E) [!] *C68K: - *FAME: - Ms. Pac-Man (U) [!] *C68K: - *FAME: - Muhammad Ali Heavyweight Boxing (U) [c][!] *C68K: - *FAME: - Mulan (Unl) [!] *C68K: - *FAME: - Mutant League Football (UE) [!] *C68K: - *FAME: - Mutant League Hockey (UE) [!] *C68K: - Runs terribly with serious GFX issues and a slow frame-rate. *FAME: - Same. Mystic Defender (W) (REV01) [!] *C68K: -Perfect *FAME: - Mystical Fighter (U) [c][!] *C68K: - *FAME: - ==N== NBA Action '95 (UE) [!] *C68K: - *FAME: - NBA Action (U) [!] *C68K: - *FAME: - NBA All-Star Challenge (UE) [!] *C68K: - *FAME: - NBA Hang Time (U) [!] *C68K: - *FAME: - NBA Jam (UE) (REV01) [!] *C68K: - *FAME: - NBA Jam Tournament Edition (W) (REV01) [!] *C68K: - *FAME: - NBA Live 95 (UE) [!] *C68K: - *FAME: - NBA Live 96 (UE) [!] *C68K: - *FAME: - NBA Live 97 (UE) [!] *C68K: - *FAME: - NBA Live 98 (U) [!] *C68K: - *FAME: - NBA Showdown 94 (UE) [!] *C68K: - *FAME: - NCAA College Football (U) [!] *C68K: - *FAME: - NCAA Final Four College Basketball (U) [!] *C68K: - *FAME: - New 3D Golf Simulation Harukanaru Augusta (J) [!] *C68K: - *FAME: - New Zealand Story, The (J) [!] *C68K: - *FAME: - Newman-Haas IndyCar Racing (W) [!] *C68K: - *FAME: - NFL '95 (U) [!] *C68K: - *FAME: - NFL 98 (U) [!] *C68K: - *FAME: - NFL Football '94 Starring Joe Montana (J) [!] *C68K: - *FAME: - NFL Prime Time (U) [!] *C68K: - *FAME: - NFL Quarterback Club (W) [!] *C68K: - *FAME: - NFL Quarterback Club 96 (UE) [!] *C68K: - *FAME: - NHL 94 (UE) [!] *C68K: - *FAME: - NHL 95 (UE) [!] *C68K: - *FAME: - NHL 96 (UE) [!] *C68K: - *FAME: - NHL 97 (UE) [!] *C68K: - *FAME: - NHL 98 (U) [c][!] *C68K: - *FAME: - NHL All-Star Hockey '95 (U) [!] *C68K: - *FAME: - NHL Hockey (U) [!] *C68K: - *FAME: - NHLPA Hockey '93 (UE) (REV01) [!] *C68K: - *FAME: - Nigel Mansell's World Championship (U) [!] *C68K: - *FAME: - Nightmare Circus (B) [!] *C68K: - *FAME: - Nikkan Sports Pro Yakyuu Van (J) [!] *C68K: - *FAME: - Ninja Burai Densetsu (J) [!] *C68K: - *FAME: - Ninja Gaiden (Beta) *C68K: - *FAME: - No Escape (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Nobunaga no Yabou - Bushou Fuuunsoku (J) [!] *C68K: - *FAME: - Nobunaga no Yabou Haouden - Lord of Darkness (J) [!] *C68K: - *FAME: - Nobunaga's Ambition (U) [!] *C68K: - *FAME: - Normy's Beach Babe-O-Rama (UE) [!] *C68K: - *FAME: - ==O== Olympic Gold - Barcelona 92 (U) (M8) [c][!] *C68K: - *FAME: - Olympic Summer Games Atlanta 96 (UE) [!] *C68K: - *FAME: - Olympic Winter Games - Lillehammer 94 (U) [c][!] *C68K: - *FAME: - Onslaught (U) [c][!] *C68K: - *FAME: - Ooze, The (JU) [!] *C68K: - *FAME: - Operation Europe - Path to Victory 1939-1945 (U) [!] *C68K: - *FAME: - Osomatsu-kun - Hachamecha Gekijou (J) [c][!] *C68K: - *FAME: - Ottifants, The (E) (M5) [!] *C68K: - *FAME: - Out of this World (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Outlander (U) [!] *C68K: - *FAME: - OutRun (W) [!] *C68K: - *FAME: - OutRun 2019 (U) [!] *C68K: - *FAME: - OutRunners (U) [!] *C68K: - *FAME: - ==P== P.T.O. Pacific Theater of Operations (U) [!] *C68K: - *FAME: - Pac-Attack (U) [!] *C68K: - Perfect. *FAME: - Freezes after Pac-man's turn ends and music is fast. Pac-Man 2 - The New Adventures (U) [!] *C68K: - *FAME: - Pac-Mania (U) [!] *C68K: - *FAME: - Pachinko Canyon (J) [!] *C68K: - *FAME: - Paddle Fighter (SN) (J) [!] *C68K: - *FAME: - Pagemaster, The (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Panorama Cotton (J) [c][!] *C68K: - *FAME: - Paperboy (UE) [!] *C68K: - *FAME: - Paperboy II (U) [!] *C68K: - *FAME: - Pat Riley Basketball (U) [!] *C68K: - *FAME: - Patlabor (J) [c][!] *C68K: - *FAME: - Pebble Beach Golf Links (U) [!] *C68K: - *FAME: - Pele! (UE) [!] *C68K: - *FAME: - Pele's World Tournament Soccer (UE) [!] *C68K: - *FAME: - Pengo (J) [!] *C68K: - *FAME: - Pete Sampras Tennis (E) (REV03) (J-Cart) [!] *C68K: - *FAME: - Pete Sampras Tennis 96 (E) [c][!] *C68K: - *FAME: - PGA European Tour (UE) [!] *C68K: - *FAME: - PGA Tour 96 (UE) [!] *C68K: - *FAME: - PGA Tour Golf (UE) (REV02) [!] *C68K: - *FAME: - PGA Tour Golf II (UE) (REV01) [!] *C68K: - *FAME: - PGA Tour Golf III (UE) [!] *C68K: - *FAME: - Phantasy Star - The End of the Millenium (U) [!] *C68K: -Works good. *FAME: - Phantasy Star IV (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Phantasy Star II (UE) (REV01) [T+POR] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Phantasy Star III - Generations of Doom (F) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Phantom 2040 (U) [!] *C68K: - *FAME: - Phelios (U) [c][!] *C68K: - *FAME: - Pink Goes to Hollywood (U) [!] *C68K: - *FAME: - Pinocchio (U) [!] *C68K: - *FAME: - Pirates of Dark Water, The (UE) *C68K: - control bug (left tilt) (controle com bug / Falcon Silva) *FAME: - Pirates! Gold (U) [!] *C68K: - *FAME: - Pit Fighter (UJE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Pitfall - The Mayan Adventure (E) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Pocahontas (U) [!] *C68K: - *FAME: - Pocket Monsters (Unl) [!] *C68K: - *FAME: - Pocket Monsters 2 (Unl) [!] *C68K: - *FAME: - Pokemon Crazy Drummer (Unl) *C68K: - *FAME: - Populous (U) [!] *C68K: - *FAME: - Populous II - Two Tribes (E) [!] *C68K: - *FAME: - Power Drive (E) (M5) [!] *C68K: - *FAME: - Power Instinct (J) [!] *C68K: Hangs. *FAME: Hangs. Power Monger (UE) [!] *C68K: - *FAME: - Powerball (U) [c][!] *C68K: - *FAME: - Predator 2 (JUE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Premier Manager (E) [!] *C68K: - *FAME: - Premier Manager 97 (E) [!] *C68K: - *FAME: - Pretty Girl Mahjongg (Ch) *C68K: - *FAME: - Primal Rage (F) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Prince of Persia (E) Beta [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - (Mega) Probotector (E) *C68K: Perfect. *FAME: Perfect. Pro Quarterback (U) [c][!] *C68K: - *FAME: - Psy-O-Blade Moving Adventure (J) [!] *C68K: - *FAME: - Psycho Pinball (E) (Oct 1994) (M5) [c][!] *C68K: - *FAME: - Puggsy (U) [!] *C68K: - Perfect. *FAME: - Too fast W/ glitches. Pulseman (J) [c][!] *C68K: Perfect. *FAME: Not Working. Punisher, The (U) [!] *C68K: - bug invisible characters (Bug, personagens invisiveis / Falcon Silva) *FAME: - Putter Golf (SN) (J) [!] *C68K: - *FAME: - Puyo Puyo (J) [!] *C68K: - *FAME: - Puyo Puyo Tsu (J) (REV01) [!] *C68K: - *FAME: - Pyramid Magic (SN) (J) [!] *C68K: - *FAME: - Pyramid Magic II (SN) (J) [!] *C68K: - *FAME: - Pyramid Magic III (SN) (J) [!] *C68K: - *FAME: - Pyramid Magic Special (SN) (J) [!] *C68K: - *FAME: - ==Q== Quack Shot Starring Donald Duck (W) (REV01) [!] *C68K: - *FAME: Great! and with sound effects but no music. Quad Challenge (U) [c][!] *C68K: - *FAME: - ==R== Race Drivin' (U) [!] *C68K: - *FAME: - Radical Rex (U) [!] *C68K: - *FAME: - Raiden Trad (JU) [!] *C68K: - *FAME: - Rainbow Islands - The Story of Bubble Bobble 2 (J) [c][!] *C68K: - *FAME: - Rambo III (W) (REV01) [!] *C68K: - bug, noise audio (Audio chiado / Falcon Silva) *FAME: - Rampart (U) [!] *C68K: - *FAME: - Ranger-X (U) [!] *C68K: Perfect. *FAME: Way too fast! Ransei no Hasha (J) [!] *C68K: - *FAME: - Rastan Saga II (U) [!] *C68K: - *FAME: - RBI Baseball 3 (U) [c][!] *C68K: - *FAME: - RBI Baseball 4 (U) [!] *C68K: - *FAME: - RBI Baseball 93 (U) [!] *C68K: - *FAME: - RBI Baseball 94 (UE) [!] *C68K: - *FAME: - Red Zone (UE) [!] *C68K: - *FAME: - Ren and Stimpy Show, The - Stimpy's Invention (U) [!] *C68K: - *FAME: - Rent A Hero (J) [T+Eng] *C68K: - *FAME: - Resq (Beta) *C68K: - *FAME: - Revenge of Shinobi, The (W) (REV00) [!] *C68K: - *FAME: Perfect! Revenge of Shinobi, The (JUE)[!] *C68K: - invisible characters *FAME: - this works perfect, or you just have a bad ROM Revolution X (UE) [!] *C68K: - *FAME: - Richard Scarry's Busytown (U) [!] *C68K: - *FAME: - Rings of Power (UE) [!] *C68K: - *FAME: - Rise of the Robots (E) [!] *C68K: - *FAME: - Risk (U) [!] *C68K: - *FAME: - Risky Woods (UE) [!] *C68K: - *FAME: - Ristar (UE) [!] *C68K: Perfect w/ minor GFX oddities *FAME: Same. Road Blasters (U) [!] *C68K: - *FAME: - Road Rash (UE) [c][!] *C68K: - Work, with bugs in video (funciona mas com bugs de video / Falcon Silva) *FAME: - Road Rash 3 (UE) [!] *C68K: - Work, with bugs in video (funciona mas com bugs de video / Falcon Silva) *FAME: - Road Rash II (UE) (REV02) [c][!] *C68K: - Work, with bugs in video (funciona mas com bugs de video / Falcon Silva) *FAME: - Robocop 3 (UE) [!] *C68K: - *FAME: - Robocop Versus The Terminator (U) [!] *C68K: - *FAME: - Rock n' Roll Racing (U) [!] *C68K: - *FAME: - Rocket Knight Adventures (U) [!] *C68K: Perfect. *FAME: Same (but: once outside of the screen, player dies immediatly) Rockman Megaworld (J) [!] *C68K: Perfect. *FAME: Not working Rockman X3 (Unl) [!] *C68K: - *FAME: - Rocky and Bullwinkle, The Adventures of (U) [!] *C68K: - *FAME: - Roger Clemens' MVP Baseball (U) [!] *C68K: - *FAME: - Rolling Thunder 2 (U) [c][!] *C68K: - *FAME: - Rolling Thunder 3 (U) [c][!] *C68K: - *FAME: - Rolo to the Rescue (UE) [!] *C68K: - *FAME: - Romance of the Three Kingdoms II (U) [!] *C68K: - *FAME: - Romance of the Three Kingdoms III (U) [!] *C68K: - *FAME: - Romance of the Three Kingdoms Part 5 (Ch) *C68K: - *FAME: - Ronaldinho 98 (B) [c][!] *C68K: - load and crash (carrega mas trava no inicio da partida / Falcon Silva) *FAME: - Rugby World Cup 1995 (UE) (M3) [!] *C68K: - *FAME: - ==S== Sagaia (U) [c][!] *C68K: Perfect. *FAME: Perfect. Sailor Moon (J) [!] *C68K: Crashes. (works with SW!) *FAME: Same. Saint Sword (U) [c][!] *C68K: - *FAME: - Same! Same! Same! (J) [!] *C68K: - *FAME: - Samurai Shodown (U) [!] *C68K: -Does not detect Controls *FAME: -Same Sangokushi Retsuden - Ransei no Eiyuu Tachi (J) [!] *C68K: - *FAME: - Saturday Night Slam Masters (U) [!] *C68K: - Works W/ minor character selection GFX glitches *FAME: - Same Scooby Doo Mystery (U) [!] *C68K: - *FAME: - Scrabble (Beta) *C68K: - *FAME: - SeaQuest DSV (U) [!] *C68K: - *FAME: - Second Samurai, The (E) *C68K: - *FAME: - Sensible Soccer (E) (M4) [!] *C68K: - *FAME: - Sensible Soccer - International Edition (E) (M4) [!] *C68K: - *FAME: - Sesame Street Counting Cafe (U) [!] *C68K: - *FAME: - Shadow Blasters (U) [c][!] *C68K: - *FAME: - Shadow Dancer - The Secret of Shinobi (W) and (JUE) [c][!] *C68K: Perfect. *FAME: - Shadow of the Beast (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Shadow of the Beast 2 (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Shadowrun (U) [!] *C68K: - *FAME: - Shane Warne Cricket (E) [c][!] *C68K: - *FAME: - Shanghai 2 - Dragon's Eye (U) [!] *C68K: - *FAME: - Shaq Fu (UE) [!] *C68K: - *FAME: - Shi Kin Joh (J) [!] *C68K: - *FAME: - Shining Force (U) [!] *C68K: - Freezes after SEGA Logo. *FAME: - Same. Shining Force II (U) [!] *C68K: - *FAME: - Shining in the Darkness (UE) [!] *C68K: - *FAME: - Shinobi III - Return of the Ninja Master (U) [!] *C68K: Perfect. *FAME: Perfect. Shogi no Hoshi (J) [!] *C68K: - *FAME: - Shove It! - The Warehouse Game (U) [!] *C68K: - *FAME: - Show do Milhao (B) [!] *C68K: - *FAME: - Show do Milhao Volume 2 (B) [!] *C68K: - *FAME: - Shura no Mon (J) [!] *C68K: - *FAME: - Side Pocket (JU) [!] *C68K: - *FAME: - Simpsons, The - Bart vs The Space Mutants (UE) (REV01) [!] *C68K: - *FAME: - Simpsons, The - Bart's Nightmare (UE) (REV02) [!] *C68K: - *FAME: - Skeleton Krew (U) [!] *C68K: - *FAME: - Skitchin' (UE) [!] *C68K: - *FAME: - Slam Dunk - Shikyou Gekitotsu! (J) [!] *C68K: - *FAME: - Slap Fight (J) [c][!] *C68K: - *FAME: - Slaughter Sport (U) [c][!] *C68K: - *FAME: - Smart Mouse (Unl) *C68K: - *FAME: - Smurfs 2, The (E) (M4) [!] *C68K: - *FAME: - Smurfs, The (E) (M5) [!] *C68K: - *FAME: - Snake Rattle 'n' Roll (E) [c][!] *C68K: - *FAME: - Snow Bros. - Nick & Tom (J) [c][!] *C68K: - Invisible characters *FAME: - Socket (U) [!] *C68K: - *FAME: - Sol-Deace (U) [!] *C68K: - *FAME: - Soldiers of Fortune (U) [c][!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Soleil (E) [!] *C68K: - Good, inventory menu keeps it from being 100% *FAME: - Freezes at SEGA logo. Soleil (S) *C68K: - *FAME: - Sonic 3D Blast (F) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Sonic Crackers (Beta) *C68K: - *FAME: - Sonic and Knuckles & Sonic 2 (JUE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Sonic and Knuckles & Sonic 3 (W) [!] *C68K: Perfect. *FAME: Hangs (?) Sonic and Knuckles (JUE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Sonic Eraser (SN) (J) [T+Eng_Derrick Sobodash] *C68K: -Gfx Errors *FAME: - Sonic Jam 6 (Unl) [!] *C68K: - *FAME: - Sonic Spinball (U) (alt music) [!] *C68K: - Good but a tad slow *FAME: - Sonic Spinball (U) [!] *C68K: - *FAME: - Sonic The Hedgehog (W) (REV01) [!] *C68K: - Perfect but has hit dectection problems *FAME: - Same Sonic The Hedgehog 2 (JUE) [!] *C68K: - Perfect! (the half-pipe roads you run on in the Emerald bonus levels are compressed and slightly blurry though) *FAME: - Sonic The Hedgehog 2 (W) (REV01) [!] *C68K: - Perfect but 2P VS. has GFX issues *FAME: - Same Sonic The Hedgehog 3 (U) [!] *C68K: - Works well W/ minor GFX issues *FAME: - Sorcerer's Kingdom (U) (REV01) [!] *C68K: - *FAME: - Sorcerian (J) [T+Eng10%_NaflignsEgo] *C68K: - *FAME: - Soul Blade (Unl) [!] *C68K: - *FAME: - Space Harrier II (UE) [!] *C68K: - Won't start *FAME: - Same Space Invaders 91 (U) [c][!] *C68K: - *FAME: - Sparkster (U) [!] *C68K: - Works really well *FAME: - Speed Ball 2 - Brutal Deluxe (U) [c][!] *C68K: - *FAME: - Spider-Man - The Animated Series (W) [!] *C68K: - *FAME: - Spider-Man and Venom - Maximum Carnage (W) [!] *C68K: - *FAME: - Spider-Man and Venom - Separation Anxiety (U) [!] *C68K: - *FAME: - Spider-Man and X-Men - Arcade's Revenge (UE) [!] *C68K: - *FAME: - Spider-Man vs The Kingpin (W) [!] *C68K: - *FAME: - Spiritual Warfare (Unl) [!] *C68K: - *FAME: - Spirou (E) [!] *C68K: - *FAME: - Splatterhouse 2 (U) [c][!] *C68K: - *FAME: - Splatterhouse 3 (U) [c][!] *C68K: - *FAME: - Spot Goes to Hollywood (U) (REV01) [!] *C68K: - *FAME: - Squirrel King (R) [!] *C68K: - *FAME: - Star Control (U) [c][!] *C68K: - *FAME: - Star Cruiser (J) [!] *C68K: - *FAME: - Star Trek - Deep Space 9 - Crossroads of Time (U) [!] *C68K: - *FAME: - Star Trek - The Next Generation (U) (REV01) [!] *C68K: - *FAME: - Starflight (UE) (REV01) [!] *C68K: - *FAME: - Stargate (UE) [!] *C68K: - *FAME: - Steel Empire, The (UE) [!] *C68K: - perfect *FAME: - Steel Talons (UE) [!] *C68K: - *FAME: - Stormlord (U) [!] *C68K: - *FAME: - Story of Thor, The - A Successor of The Light (S) *C68K: - *FAME: - Street Fighter II' - Special Champion Edition (U) [!] *C68K: - Perfect *FAME: - Street Fighter II' Turbo (Beta) *C68K: Perfect. *FAME: Hangs at the title screen. Street Racer (E) [c][!] *C68K: - *FAME: - Street Smart (JU) [!] *C68K: - *FAME: - Streets of Rage (W) (REV01) [!] *C68K: Perfect. *FAME: Perfect. Streets of Rage 2 (U) [!] *C68K: Perfect. *FAME: Perfect. Streets of Rage 3 (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Strider (UE) [!] *C68K: - *FAME: - Strider II (E) [c][!] *C68K: - *FAME: - Striker (E) (M5) [!] *C68K: - *FAME: - Sub-Terrania (U) [!] *C68K: - *FAME: - Summer Challenge (U) [!] *C68K: - *FAME: - Sunset Riders (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Super Airwolf (J) [!] *C68K: - *FAME: - Super Baseball 2020 (UE) [!] *C68K: - *FAME: - Super Battle Tank - War in the Gulf (U) [!] *C68K: - *FAME: - Super Battleship (U) [!] *C68K: - *FAME: - Super Bubble Bobble (Unl) [!] *C68K: - *FAME: - Super Chinese Tycoon (Unl) [f1] *C68K: - *FAME: - Super Daisenryaku (J) (REV00) [!] *C68K: - *FAME: - Super Donkey Kong 99 (Unl) [!] *C68K: - *FAME: - Super Fantasy Zone (E) [!] *C68K: - *FAME: - Super Hang-On (W) (REV01) [!] *C68K: - *FAME: - Super High Impact (UE) [!] *C68K: - *FAME: - Super Hydlide (U) [!] *C68K: - *FAME: - Super Kick Off (E) [c][!] *C68K: - *FAME: - Super League 91 (J) [!] *C68K: - *FAME: - Super Mario 2 1998 (Unl) [!] *C68K: - *FAME: - Super Mario Bros. (Unl) [!] *C68K: - *FAME: - Super Mario World (Unl) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Super Monaco Grand Prix (W) (M2) (REV02) [!] *C68K: - *FAME: - Super Off Road (U) [!] *C68K: - *FAME: - Super Skidmarks (E) (J-Cart) [!] *C68K: - *FAME: - Super Smash TV (UE) [!] *C68K: - *FAME: - Super Street Fighter II - The New Challengers (U) [c][!] *C68K: - not load (não carrega / Falcon Silva) *FAME: - Super Thunder Blade (W) (REV01) [!] *C68K: - *FAME: - Super Volleyball (U) [c][!] *C68K: - *FAME: - Superman (U) [!] *C68K: - *FAME: - Surging Aura (J) [!] *C68K: - *FAME: - Sword of Sodan (UE) [!] *C68K: - *FAME: - Sword of Vermilion (UE) [!] *C68K: - *FAME: - Syd of Valis (U) [!] *C68K: - *FAME: - Sylvester & Tweety in Cagey Capers (UE) [!] *C68K: - *FAME: - Syndicate (UE) [!] *C68K: - *FAME: - ==T== T2 - The Arcade Game (UE) (REV01) [!] *C68K: - *FAME: - Taiga Drama Taiheiki (J) [!] *C68K: - *FAME: - Taikou Risshiden (J) [!] *C68K: - *FAME: - Taiwan Tycoon (Unl) *C68K: - *FAME: - Tale Spin (UE) [!] *C68K: - *FAME: - Tanto R (J) [!] *C68K: - *FAME: - Target Earth (U) [!] *C68K: - *FAME: - Task Force Harrier EX (U) [!] *C68K: - *FAME: - Taz-Mania (W) [!] *C68K: - *FAME: - Team USA Basketball (UE) [c][!] *C68K: - *FAME: - Techno Clash (UE) [!] *C68K: - *FAME: - Technocop (U) [!] *C68K: - *FAME: - Tecmo Cup (J) [h1C] *C68K: - *FAME: - Tecmo Super Baseball (U) [!] *C68K: - *FAME: - Tecmo Super Bowl (U) (Oct 1993) [!] *C68K: - *FAME: - Tecmo Super Bowl II SE (U) [!] *C68K: - *FAME: - Tecmo Super Bowl III Final Edition (U) [!] *C68K: - *FAME: - Tecmo Super Hockey (U) [!] *C68K: - *FAME: - Tecmo Super NBA Basketball (U) [!] *C68K: - *FAME: - Tecmo World Cup '93 (U) [!] *C68K: - *FAME: - Teenage Mutant Ninja Turtles - The Hyperstone Heist (U) [!] *C68K: - Perfect *FAME: - Teenage Mutant Ninja Turtles - Tournament Fighters (U) [c][!] *C68K: - *FAME: - Tekken 3 Special (Unl) *C68K: - *FAME: - Tel Tel Mahjong (J) [c][!] *C68K: - *FAME: - Tel Tel Stadium (J) [!] *C68K: - *FAME: - Telebradesco Residencia (B) [!] *C68K: - *FAME: - Terminator 2 - Judgment Day (UE) [!] *C68K: - *FAME: - Terminator, The (U) [!] *C68K: - *FAME: - Test Drive II - The Duel (U) [!] *C68K: - *FAME: - Tetris (J) [!] *C68K: - *FAME: - Theme Park (UE) [!] *C68K: - *FAME: - Thomas the Tank Engine & Friends (U) [c][!] *C68K: - *FAME: - Thunder Force II (U) [!] *C68K: - *FAME: - Thunder Force III (JU) [!] *C68K: - Fullspeed and sound, gfx errors *FAME: - Thunder Force IV (E) [c][!] *C68K: - *FAME: - Thunder Fox (U) [c][!] *C68K: - *FAME: - Tick, The (U) [!] *C68K: - *FAME: - Tiger Hunter Hero Novel (Ch) *C68K: - *FAME: - Time Killers (U) [!] *C68K: - *FAME: - Tinhead (U) [!] *C68K: - *FAME: - Tintin Au Tibet (E) (M6) [!] *C68K: - *FAME: - Tiny Toon Adventures - Acme All-Stars (U) [!] *C68K: - Perfect *FAME: - Tiny Toon Adventures - Buster's Hidden Treasure (U) [!] *C68K: - *FAME: - TMNT - T.H.S.H (E) *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - TMNT - Tournament Fighters (E) *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - TNN Bass Tournament of Champions (U) (REV01) [!] *C68K: - *FAME: - TNN Outdoors Bass Tournament '96 (U) [!] *C68K: - *FAME: - Todd's Adventures in Slime World (U) [!] *C68K: - *FAME: - Toejam & Earl (U) (REV00) [!] *C68K: - Works well but slow in places *FAME: - Toejam & Earl in Panic on Funkotron (U) [!] *C68K: Perfect W/ lower-pitch voices *FAME: Hangs. Toki - Going Ape Spit (UE) [c][!] *C68K: - *FAME: - Tom and Jerry - Frantic Antics (U) (1994) [!] *C68K: - *FAME: - Tommy Lasorda Baseball (U) [!] *C68K: - *FAME: - Tony La Russa Baseball (U) [!] *C68K: - *FAME: - Tony La Russa Baseball 95 (U) [!] *C68K: - *FAME: - Top Fighter 2000 MK VIII (Unl) [!] *C68K: - *FAME: - Top Gear 2 (U) [!] *C68K: - Work, with bugs in video (funciona mas com bugs de video / Falcon Silva) *FAME: - Top Pro Golf (J) [!] *C68K: - *FAME: - Top Shooter (Unl) *C68K: - *FAME: - Total Football (E) [!] *C68K: - *FAME: - Toughman Contest (UE) [!] *C68K: - *FAME: - Toxic Crusaders (U) [!] *C68K: - *FAME: - Toy Story (U) [!] *C68K: - *FAME: - Toy Story (4) [!] *C68K: - Very Good [There are glitches on the screen] *FAME: - Very Good [during game play and start screens] Toys (U) [!] *C68K: - *FAME: - Trampoline Terror! (U) [!] *C68K: - *FAME: - Traysia (U) [!] *C68K: - *FAME: - Triple Play '96 (U) [c][!] *C68K: - *FAME: - Triple Play Gold (U) [c][!] *C68K: - *FAME: - Trouble Shooter (U) [!] *C68K: - *FAME: - Troy Aikman NFL Football (U) [!] *C68K: - *FAME: - True Lies (W) [!] *C68K: - *FAME: - Truxton (W) [!] *C68K: Graphics + sounds are distorted. *FAME: Same. Turbo Outrun (JE) [c][!] *C68K: - *FAME: - Turma da Monica na Terra Dos Monstros (B) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Turrican (U) [c][!] *C68K: - *FAME: - Twin Cobra (U) [!] *C68K: - *FAME: - Twin Hawk (JE) [!] *C68K: - *FAME: - Twinkle Tale (J) [!] *C68K: - *FAME: - Two Crude Dudes (U) [!] *C68K: - *FAME: - Tyrants - Fight Through Time (U) [!] *C68K: - *FAME: - ==U== Uchu Senkan Gomora (J) [c][!] *C68K: - *FAME: - Ultimate Mortal Kombat 3 (U) [!] *C68K: - perfect! (perfeito!) *FAME: - Ultimate Qix (U) [!] *C68K: - *FAME: - Ultimate Soccer (E) [!] *C68K: - *FAME: - Ultraman (J) [!] *C68K: - *FAME: - Uncharted Waters (U) [!] *C68K: - *FAME: - Uncharted Waters - New Horizons (U) [!] *C68K: - *FAME: - Undead Line (J) [!] *C68K: - *FAME: - Universal Soldier (U) [!] *C68K: - *FAME: - Unknown Chinese Game 1 (Ch) *C68K: - *FAME: - Unknown Chinese Game 2 (Ch) *C68K: - *FAME: - Unnecessary Roughness 95 (U) [!] *C68K: - *FAME: - Urban Strike (UE) [!] *C68K: - *FAME: - Uzu Keobukseon (K) [!] *C68K: - *FAME: - ==V== Valis (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Valis III (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Vapor Trail (U) [!] *C68K: - *FAME: - Vectorman (UE) [!] *C68K: - *FAME: Perfect. Vectorman 2 (U) [!] *C68K: - *FAME: Perfect. Verytex (J) [c][!] *C68K: - *FAME: - Viewpoint (U) [!] *C68K: - *FAME: - Virtua Fighter 2 (F) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Virtua Fighter 2 vs Tekken 2 (Unl) *C68K: - *FAME: - Virtua Racing (U) [!] *C68K: - *FAME: - Virtual Bart (W) [!] *C68K: - *FAME: - Virtual Pinball (UE) [!] *C68K: - *FAME: - Vixen 357 (J) [!] *C68K: - *FAME: - VR Troopers (UE) [!] *C68K: - *FAME: - ==W== Wacky Races (Beta) *C68K: - *FAME: - Wacky Worlds (U) [!] *C68K: - *FAME: - Waialae no Kiseki (J) [!] *C68K: - *FAME: - Wani Wani World (J) [c][!] *C68K: - *FAME: - Wardner (U) [!] *C68K: - *FAME: - Warlock (UE) [!] *C68K: - *FAME: - Warpspeed (U) [!] *C68K: - *FAME: - Warrior of Rome (U) [!] *C68K: - *FAME: - Warrior of Rome II (U) [c][!] *C68K: - *FAME: - Warsong (U) [!] *C68K: - Freezes at title screen *FAME: - Same Waterworld (Beta) *C68K: - *FAME: - Wayne Gretzsky NHLPA All-Stars (UE) [!] *C68K: - *FAME: - Wayne's World (U) [c][!] *C68K: - *FAME: - We're Back! - A Dinosaur's Tale (U) [!] *C68K: - *FAME: - Weaponlord (U) [!] *C68K: - *FAME: - Whac-A-Critter (Unl) [!] *C68K: - *FAME: - Wheel of Fortune (U) [!] *C68K: - *FAME: - Where in the World is Carmen Sandiego (U) *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Where in Time is Carmen Sandiego (UE) (M5) [!] *C68K: - *FAME: - Whip Rush 2222 AD (U) [!] *C68K: - *FAME: - Wild Snake (U) (Prototype) [!] *C68K: - *FAME: - Williams Arcade's Greatest Hits (U) [!] *C68K: - *FAME: - Wimbledon Championship Tennis (U) [!] *C68K: - *FAME: - Wings of Wor (U) [!] *C68K: - *FAME: - Winter Challenge (UE) [!] *C68K: - *FAME: - Wiz 'n' Liz - The Frantic Wabbit Wescue (U) [!] *C68K: - *FAME: - Wolf Child (U) [c][!] *C68K: - *FAME: - Wolverine Adamantium Rage (JUE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Wonder Boy III - Monster Lair (JE) [c][!] *C68K: - *FAME: - Wonder Boy in Monster World (UE) [!] *C68K: blocked after START (version (UE) [o1][b1] works great with C68K but no save ...) *FAME: blocked after START (version (UE) [o1][b1] works great with FAME but no save ...) Wonder Boy in Monster World (UE) [h1C] *C68k: HW - Good, minor sound lag *FAME: - World Championship Soccer (JU) (REV03) [!] *C68K: - *FAME: - World Championship Soccer II (U) [!] *C68K: - *FAME: - World Class Leaderboard Golf (U) [c][!] *C68K: - *FAME: - World Cup Italia 90 (E) [!] *C68K: - *FAME: - World Cup USA 94 (UE) [!] *C68K: - *FAME: - World Heroes (U) [!] *C68K: - *FAME: - World of Illusion Starring Mickey Mouse & Donald Duck (U) [!] *C68K: - *FAME: - World Pro Baseball 94 (Unl) *C68K: - *FAME: - World Series Baseball '95 (U) [!] *C68K: - *FAME: - World Series Baseball '96 (U) [!] *C68K: - *FAME: - World Series Baseball '98 (U) [!] *C68K: - *FAME: - World Series Baseball (U) [!] *C68K: - *FAME: - World Trophy Soccer (U) [!] *C68K: - *FAME: - Worms (E) [!] *C68K: - *FAME: - Wrestle War (JE) [c][!] *C68K: - *FAME: - WWF RAW (W) [!] *C68K: - *FAME: - WWF Royal Rumble (W) [!] *C68K: - *FAME: - WWF Super Wrestlemania (UE) [!] *C68K: - *FAME: - WWF Wrestlemania Arcade (U) [!] *C68K: - *FAME: - ==X== X Dazedly Ray (J) [!] *C68K: - *FAME: - X-Men (U) [!] *C68K: - *FAME: - X-Men 2 - Clone Wars (JUE) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - X-perts (U) [!] *C68K: - *FAME: - Xenon 2 - Megablast (E) [c][!] *C68K: - *FAME: - Xin Qi Gai Wang Zi (Ch) *C68K: - *FAME: - ==Y== Ya-Se Chuan Shuo (Ch) *C68K: - *FAME: - Yang Warrior Family, The (Ch) *C68K: - *FAME: - Yogi Bear's Cartoon Capers (E) [!] *C68K: - *FAME: - Young Indiana Jones - Instrument of Chaos (U) [!] *C68K: - Perfect! (Perfeito! / Falcon Silva) *FAME: - Young Indiana Jones Chronicles (Beta) *C68K: - *FAME: - Ys III - Wanderers from Ys (U) [!] *C68K: - *FAME: - Yuu Yuu Hakusho - Sunset Fighters (B) [!] *C68K: - *FAME: - Yuu Yuu Hakusho Gaiden (J) [!] *C68K: - *FAME: - ==Z== Zan Yasha Enbuden (J) [!] *C68K: - *FAME: - Zany Golf (UE) (REV01) *C68K: - *FAME: - Zero the Kamikaze Squirrel (U) [!] *C68K: - *FAME: - Zero Tolerance (UE) [!] *C68K: - *FAME: - Zero Wing (E) [c][!] *C68K: - Characters are invisible *FAME: - Player sprite invisible Zombie High (U) (Prototype) *C68K: - *FAME: - Zombies Ate My Neighbors (U) [c][!] *C68K: - Perfect *FAME: - Zool (U) [!] *C68K: - *FAME: - Zoom! (JU) [!] *C68K: - *FAME: - Zoop (U) [!] *C68K: - *FAME: - ---- 72e46038f7982c95fc4bfadfb1d7ccd9f1a4c7b5 DCGenerator 0 841 1991 2023-03-01T20:16:29Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DCGenerator| homepage=[http://dcgen.sourceforge.net/ Homepage]| version=0.35| downloads=[http://dcemulation.org/1-newsdump/emulators/d..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCGenerator| homepage=[http://dcgen.sourceforge.net/ Homepage]| version=0.35| downloads=[http://dcemulation.org/1-newsdump/emulators/dcgen.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/emulators/dcgens.zip Sourcecode]| release date=05/24/03| author=[[ATani]] & [[MetaFox]]| original=[http://www.squish.net/generator/ Generator]<br/>by James Ponder| systems=Sega Genesis| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=[http://dcemulation.org/1-newsdump/emulators/dcgen-0.34.zip 0.34]<br/>11/02/01| best=No. We recommend<br/>[[Genesis Plus DC]]| isactive=No }} DCGenerator was the first Sega Genesis emulator ported to the Sega Dreamcast. It was meant as a [[GPL|free]] alternative to the Sega Genesis emulator used in [[Sega Smash Pack Volume 1]]. DCGenerator has been discontinued in 2002. Today, [[Genesis Plus DC]] is the best Sega Genesis emulator available. =Known bugs= * Some games still cause crashes * Sound is totally disabled * Video is still too slow * Slow/Complex (non-Simple) render mode has problems on some games. =Controls= '''Game Selection Key mappings'''<br/> *A - Selects Game *B - Backup/abort *L - Up 15 entries *R - Down 15 entries *Y - Rescan CD '''Options Screen Key Mappings'''<br/> *A - Enable/Disable Yes/No options *A - Increase auto Frameskip Count *B - Decrease auto Frameskip Count *START - Exit Options Screen '''Sega Genesis Controller'''<br/> *X - A *A - B *B - C '''Special Keys'''<br/> *L - Mode Change *R - Reset *L&R - Exit to Menu =Older Versions= *[http://dcemulation.org/1-newsdump/emulators/dcgen-0.34.zip 0.34 Plain Files] - 11/02/01 *[http://www.dcemulation.org/files/emulators/DCGen_034b_Nero.zip 0.34b Nero Image] - 04/11/02 *[http://www.dcemulation.org/files/emulators/DCGen_034b_DJ.zip 0.34b DiscJuggler Image] - 04/11/02 b2419dc231638b8845bf2a3d0a544f84b7d8d577 Ljsdcgen 0 842 1992 2023-03-01T20:16:51Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=ljsdcgen| homepage=[http://www.ljsdcdev.net Homepage]| version=1| downloads=[http://downloads.sourceforge.net/ljsdcdev/ljsdcgen-v1-bin..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=ljsdcgen| homepage=[http://www.ljsdcdev.net Homepage]| version=1| downloads=[http://downloads.sourceforge.net/ljsdcdev/ljsdcgen-v1-bin.tar.bz2?modtime=1053216000&big_mirror=0 Plain Files]<br/>[http://downloads.sourceforge.net/ljsdcdev/ljsdcgen-v1-src.tar.bz2?modtime=1053216000&big_mirror=0 Source Code]| release date=5/17/03| author=Lawrence Sebald<br/>(BlueCrab)| original=[http://www.squish.net/generator/ Generator]<br/>by James Ponder| systems=Sega Genesis| firstversion=[http://downloads.sourceforge.net/ljsdcdev/ljsdcgen-v1-bin.tar.bz2?modtime=1053216000&big_mirror=0 1]<br/>5/17/03| best=No| refreshrate=60Hz| isactive=No }} ljsdcgen is a port of James Ponder's Generator to the Dreamcast using SDL. This emulator was discontinued shortly after its first release. =Known bugs= *It is very very slow. ddf6e4ab5ded7f6d317b5d6fdb142e49074a9e83 Emulators on Dreamcast 0 108 1993 1401 2023-03-01T20:18:14Z Unknown user 0 /* Sega CD/Mega CD */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[PSX4ALL]] *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 75b840ecd9319dd41e48ff8e8235cc7b8f7834be 2022 1993 2023-03-01T20:37:50Z Unknown user 0 /* Sony PlayStation */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[Sarien]] *[[ScummVM]] (Lucas Arts Adventures) 873d4e67afe419ec29948a5965dfb9defed39a34 File:Smsplus.png 6 843 1994 2023-03-01T20:18:43Z Unknown user 0 wikitext text/x-wiki Smsplus a70659da7349d37767bd2d732f151c5b4197515f SMS Plus DC 0 844 1995 2023-03-01T20:18:52Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SMS Plus DC| image=[[File:smsplus.png|center|250px]]| homepage=[http://www.pascalorama.info/article.php?news=19&cat=8 Homepage]| versi..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS Plus DC| image=[[File:smsplus.png|center|250px]]| homepage=[http://www.pascalorama.info/article.php?news=19&cat=8 Homepage]| version=0.2b| downloads=[http://www.maturion.de/dreamcast/dateien/emulatoren/smsplusdc/smsplusdcv02b.zip Plain Files]<br />[http://www.maturion.de/dreamcast/dateien/emulatoren/smsplusdc/smsplusdcv02bsrc.zip Source Code]| release date=February 20, 2005| author=[[Pascal Bosquet]]<br />Help by [[Heliophobe]]| original=[http://cgfm2.emuviews.com/smsplus.php SMS Plus]| systems=Master System, GameGear| best=Yes| refreshrate=50Hz/60Hz| isactive=No }} SMS Plus DC is the best MasterSystem/Gamegear emulator for the Dreamcast console. It was mostly developed by [[Pascal Bosquet]]. It runs fullspeed, without frameskipping and with sound enabled. ==Features== *No frameskip with sound *Hi-res display (640*480) *Intuitive GUI *Two players *Bilinear filtering *Speech emulation *Sram and game state saving *Screen Adjustment *Great compatibility *PAL support *Rom snapshot preview in the gui *Speed: 99% *Sound: 99% ==Links== *[http://www.pascalorama.info/article.php?news=19&cat=8 Official website] b1f09c4b7744d6fcbd0a6f88e766c38fbf81e196 File:SMEG 04.jpg 6 845 1996 2023-03-01T20:19:31Z Unknown user 0 wikitext text/x-wiki SMEG 04 a6ca5731d1991e3ca0f56e33f931061c054b11b8 SMEG 0 846 1997 2023-03-01T20:19:39Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SMEG| homepage=[http://www.smspower.org/heliophobe/ Homepage]| version=0.84| image=[[File:SMEG 04.jpg|center|250px]]| download..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMEG| homepage=[http://www.smspower.org/heliophobe/ Homepage]| version=0.84| image=[[File:SMEG 04.jpg|center|250px]]| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/smeg_084_plain.zip Plain Files]<br/>[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/smeg_084_nero.zip Nero Image]<br/>[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/smeg_084_dj.zip DiscJuggler image]<br/> [http://www.dcemulation.org/?title=SMEG.nfo Info File]| release date=10/14/01| author=[[Heliophobe]]| original=Nothing| systems=Master System<br/>GameGear| best=No, we recommend<br/>[[SMS Plus DC]]| isactive=No| refreshrate=50Hz \ 60Hz }} Smeg is an emulator the Sega Master System (SMS) and Game Gear (GG) game consoles, which runs on the Sega Dreamcast console. It features full speed, excellent sound but it lacks any sort of save support. Two players are supported. ==Known Bugs== * No Save Support * Some Games are Incompatible * Rom Loader Flaky when no disc is inserted, or no roms are found on disc * 50hz gameplay makes speech playback choppy * Out Run 3D won't detect paddle controller (even though supported) ==Controls== Dreamcast \ SMS or GG * D-Pad \ D-Pad * A and B \ 1 and 2 (reversible) * Start \ Pause (SMS), Start (GG) * X + Start to do soft reset * Y Returns to SMEG menu * Analog stick \ Controls Paddle (SMS) 33b0a0f5d7ca69534f64c6f67685049135a535f5 SMS Plus 0 847 1998 2023-03-01T20:21:16Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SMS Plus| image=No screenshot available| homepage=[http://devcast.wolfnet.org/ Homepage]| version=Beta 7| downloads= [http://w..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS Plus| image=No screenshot available| homepage=[http://devcast.wolfnet.org/ Homepage]| version=Beta 7| downloads= [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/smsplus7.zip Plain Files]<br/>| release date=Unknown| author=ss_teven| original=Charles Mac Donald| systems=Sega Master System Game Gear| best=No.| isactive=No }} Developer: [http://devcast.wolfnet.org/ ss_teven - DevCast] Version: Beta 7 Last Updated: 07-14-01 This is a very simple port of SMS Plus by Charles Mac Donald to the Dreamcast. Size [http://www.dcemulation.org/newhelp/selfboot.php?item=SMS%20Plus%20Beta%207&binfile=smsplus.bin SMS Plus Beta 7 Self Boot Plain Files Tutorial] =Old Versions= [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/smsplus62.zip Plain Files Version] Beta 6.1 [[Category:Emulator]] 372c1d3093a40322e394c12c4db41785f7e0e46b File:Sms-001s.jpg 6 848 1999 2023-03-01T20:22:49Z Unknown user 0 wikitext text/x-wiki Sms-001s ac12ee291bf9b72808e9061f70a78dd86528cb55 File:Sms-004s.jpg 6 849 2000 2023-03-01T20:22:56Z Unknown user 0 wikitext text/x-wiki Sms-004s cd488cf1a3ad004e62d81980be27a66436d2c2e8 File:Sms-005s.jpg 6 850 2001 2023-03-01T20:23:03Z Unknown user 0 wikitext text/x-wiki Sms-005s f14df5378db4f5f6f7392a1b8ffccf63492f95f1 DreamSMS 0 851 2002 2023-03-01T20:23:18Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DreamSMS| image=See below| homepage=Unknown| version=.01| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSMS| image=See below| homepage=Unknown| version=.01| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreamsms01.zip Plain Files] - 03/06/01<br/>| release date=Unknown| author=Jos Kwanten| original=N/A| systems=Sega Master System / Game Gear| best=Unknown| isactive=Unknown }} Developer: Jos Kwanten Version: .01 Last Updated: 03-06-01 A Sega Master System emulator for the Dreamcast which runs Game Gear games as well. Made by the same guy who brought us the MSX emulator. Only runs Game Gear games at this point. Status: Running full speed with sound. ==Screen Shots== [[Image:sms-001s.jpg]] [[Image:sms-004s.jpg]] [[Image:sms-005s.jpg]] ==Downloads== [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreamsms01.zip Plain Files] 10ffa0a265241d2cae5afcf68ca58731e1f21098 SMS+SDL\DC 0 852 2003 2023-03-01T20:23:46Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SMS+SDL\DC| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.1| downloads=[http://dchelp.dcemulation.org/downloads/smssdl..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS+SDL\DC| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.1| downloads=[http://dchelp.dcemulation.org/downloads/smssdldc_01.zip Plain Files]<br/>[http://dchelp.dcemulation.org/downloads/smssdldc_01_src.zip Sourcecode]| release date=4/01/08| author=[[fackue]]| original=[http://cyxdown.free.fr/ SMS+SDL]<br/>by Gregory Montoir| systems=GameGear<br/>Master System| refreshrate=60Hz| best=No. We recommend<br/>[[SMS Plus DC]]| isactive=No }} SMS+SDL was a port done by [[fackue]] as an attempt to get more familiar with Dreamcast programming. Though the port works and runs at full speed with sound, he's said that it's unlikely he will continue development. You can discuss about SMS+SDL\DC in [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=96944 the official release thread in our forums]. ==Known Bugs== * No way to get back to menu after loading game 0668cf05498fe08c43f18786055bf294a2088792 File:Dorama-screen3.jpg 6 853 2004 2023-03-01T20:25:20Z Unknown user 0 wikitext text/x-wiki Dorama-screen3 0b36a67cc50995e429d68c17d2310760a2374ce0 File:Dorama-screen1.gif 6 854 2005 2023-03-01T20:25:43Z Unknown user 0 wikitext text/x-wiki Dorama-screen1 d92b6525555d49596d1afba757f9322affbcfa92 File:Dorama-screen2.gif 6 855 2006 2023-03-01T20:25:51Z Unknown user 0 wikitext text/x-wiki Dorama-screen2 b807b17a85fa5d37b20b95d69b6b0c9b8feaba51 Dream-O-Rama 0 856 2007 2023-03-01T20:25:56Z Unknown user 0 Created page with "Developer: Spoutnick Team Version: Vol #1 Last Updated: 05-28-01 A new Sega SG-1000/3000 emulator based on the Past-O-Rama engine. * 100% speed with high quality sound..." wikitext text/x-wiki Developer: Spoutnick Team Version: Vol #1 Last Updated: 05-28-01 A new Sega SG-1000/3000 emulator based on the Past-O-Rama engine. * 100% speed with high quality sound * Hi-res display (640*480) and intuitive G.U.I. * Great compatibility and 2 players option Screen Shots: [[Image:Dorama-screen3.jpg]] [[Image:Dorama-screen2.gif]] [[Image:Dorama-screen1.gif]] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dorsg1kdij.zip Disk Juggler] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dorsg1ksc.zip Plain Files] scrambled [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dorsg1k.zip Plain Files] unscrambled [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dream-O-Rama%20Volume%20#1&filename=dorsg1kdij.zip&imagefile=dorsg1000.cdi Dream-O-Rama Volume #1 Disc Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/romdisknodirnero.php?item=Dream-O-Rama%20Volume%20#1 Dream-O-Rama Volume #1 Rom Disk Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dream-O-Rama%20Volume%20#1&binfile=1st_read.bin Dream-O-Rama Volume #1 Self Boot Plain Files Tutorial] a878b6f9eadfb6eeab42178792d54ab8163eea6b File:Yabause-20061218-5.png 6 857 2008 2023-03-01T20:26:30Z Unknown user 0 wikitext text/x-wiki Yabause-20061218-5 f1a4770a4ab6924f50f558c6884876f7963bce24 Yabause 0 858 2009 2023-03-01T20:26:39Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Yabause| image=[[Image:Yabause-20061218-5.png|center|250px]]| homepage=[http://yabause.org Homepage]| version=0.9.11| download..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Yabause| image=[[Image:Yabause-20061218-5.png|center|250px]]| homepage=[http://yabause.org Homepage]| version=0.9.11| downloads=[http://sourceforge.net/projects/yabause/files/yabause/0.9.11/yabause-0.9.11-dc.tar.bz2/download Plain Files]<br/>[http://sourceforge.net/projects/yabause/files/yabause/0.9.11/yabause-0.9.11.tar.gz/download Source Code]| release date=11/28/11| author=Lawrence Sebald<br/>([[BlueCrab]])| original=[http://yabause.org Yabause]<br/>by the Yabause team| systems=Sega Saturn| best=Yes| refreshrate=60Hz| isactive=Yes }} Yabause is a multi-platform, open-source Sega Saturn emulator. The Dreamcast port is maintained by [[BlueCrab]]. The Dreamcast port tops out at 10FPS, but will not generally reach that speed during normal game play (expect around 4FPS in games). =Known bugs= *Yabause is nowhere near full-speed on the Dreamcast and it probably won't be for a long time. *There are still many unsupported features of the Saturn hardware. =Controls= '''User Interface'''<br/> *Press START to boot the CD that is currently in the Dreamcast's GD-ROM drive. '''Buttons'''<br/> *A - A *B - B *X - X *Y - Y *L - L *R - R * Joystick Right - C * Joystick Down - Z *START - START *Directional Pad - Directional Pad 58b57fd840fc55698abfc831308b0b99a31a6966 2010 2009 2023-03-01T20:26:45Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Yabause| image=[[File:Yabause-20061218-5.png|center|250px]]| homepage=[http://yabause.org Homepage]| version=0.9.11| downloads=[http://sourceforge.net/projects/yabause/files/yabause/0.9.11/yabause-0.9.11-dc.tar.bz2/download Plain Files]<br/>[http://sourceforge.net/projects/yabause/files/yabause/0.9.11/yabause-0.9.11.tar.gz/download Source Code]| release date=11/28/11| author=Lawrence Sebald<br/>([[BlueCrab]])| original=[http://yabause.org Yabause]<br/>by the Yabause team| systems=Sega Saturn| best=Yes| refreshrate=60Hz| isactive=Yes }} Yabause is a multi-platform, open-source Sega Saturn emulator. The Dreamcast port is maintained by [[BlueCrab]]. The Dreamcast port tops out at 10FPS, but will not generally reach that speed during normal game play (expect around 4FPS in games). =Known bugs= *Yabause is nowhere near full-speed on the Dreamcast and it probably won't be for a long time. *There are still many unsupported features of the Saturn hardware. =Controls= '''User Interface'''<br/> *Press START to boot the CD that is currently in the Dreamcast's GD-ROM drive. '''Buttons'''<br/> *A - A *B - B *X - X *Y - Y *L - L *R - R * Joystick Right - C * Joystick Down - Z *START - START *Directional Pad - Directional Pad 75563e4a1b981272073435718e4e8784af472407 MDCNG 0 859 2011 2023-03-01T20:30:28Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=MDCNG| image=''No Image Available| homepage=[http://dev.dcemulation.org/mamed/neomaim.html Homepage]| version=v2.82| downloads..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=MDCNG| image=''No Image Available| homepage=[http://dev.dcemulation.org/mamed/neomaim.html Homepage]| version=v2.82| downloads=[http://www.dcemulation.org/files/emulators/MDCNGv2.82.zip Plainfiles]| release date=05/07/2003| author=[[Warmtoe]]| original=[MAME]| systems=Neo-Geo| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=''Unknown| best=No,<br/>[[AES4All]]| isactive=No| }} ==History== A NeoGeo emulator for the Dreamcast. MDCNG ''(a.k.a. NeoGeo Maim)'' has a nice GUI and tons of options! It's very like [[Maim]] - but quicker. Sound makes everything slower - but it does work... ==Downloads== * v2.82 - [http://www.dcemulation.org/files/emulators/MDCNGv2.82.zip Plainfiles] - 05/07/2003 * v2.82 - [http://www.dcemulation.org/files/sbi3.0/Mdcng-2.82.sbi SBI] - 05/07/2003 * v2.7 - [http://dev.dcemulation.org/mamed/MDCNGv2.7.zip Plainfiles] - ''Unknown release date 7687d4b19620c87cf6e4138ec9da6288a517e05d File:Aerofight.gif 6 860 2012 2023-03-01T20:31:29Z Unknown user 0 wikitext text/x-wiki Aerofight 4ca283fcc803bbf7100fd7d5a32452f197db2b27 File:Artfight.gif 6 861 2013 2023-03-01T20:31:36Z Unknown user 0 wikitext text/x-wiki Artfight 130aba6dec9e319836821394c2c88959e8b96296 File:Neo4all.png 6 862 2014 2023-03-01T20:31:43Z Unknown user 0 wikitext text/x-wiki Neo4all 5f0f3f4c0ff85e6030563855ee6198ae3493ab21 File:Puzzbob.gif 6 863 2015 2023-03-01T20:31:49Z Unknown user 0 wikitext text/x-wiki Puzzbob e297f292f555a0fa295df831f36b0bab4cca7963 AES4All 0 864 2016 2023-03-01T20:31:55Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=AES4ALL| image=[[Image:neo4all.png|center|280px| Metal Slug 2]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 2| downlo..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=AES4ALL| image=[[Image:neo4all.png|center|280px| Metal Slug 2]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 2| downloads=[http://chui.dcemu.co.uk/releases/aes4all-beta2-fix.rar Plainfiles]| release date=04/04/2007| author=[[Chui]]<br/>| original=[[NeoCD/SDL_DC|NeoCD DC]]/<br/>[http://gngeo.berlios.de/ GnGeo]/<br/>[http://pacifi3d.retrogames.com/neocdsdl/index.html NeoCD/SDL]| systems=NeoGeo AES/MVS| best=Yes.| refreshrate=50Hz / 60Hz| isactive=Unknown }} ==History== AES4ALL ''(a.k.a. Neo4all/AES)'' is a fork of Neo4all by [[Chui]], and emulates the NeoGeo AES/MVS video game system. The current release offers amazing compatibility and full speed emulation with full BGM and SFX. Beta 2 introduces a brandnew GUI with customizable controls, a rewrite of the Yamaha 2610 FM emulator, the latest FAME and FAZE versions, much faster ROM loading and an additional MMU cache level which enables to use the Dreamcast's 2MByte SRAM. To use the maximum amount of the Dreamcast's RAM, it even allows standalone single game discs which avoid loading the menu and boot straight to the game. [[Image:Puzzbob.gif| Puzzle Bobble]] ===Features=== * Emulates Neo Geo MVS & AES games * 100% full speed without frameskip on most games * 2 Player support * Great compatibility * MMU technique for playing games larger than the DC's RAM * Second MMU cache level using the Dreamcast's SRAM (+2MByte) * Full VMU Support * Region Selection * Nice GUI with Music * Arcade Stick Support * Customizable Controls * Safe Reset Function * Standalone CD Feature (the emu + your game on 1 CD) * Low level CD-ROM access for fast CD swap. * Super fast ROM loading * Main CPU Motorola 68000: * FAME emulation library by Fox68k * Sound CPU Zilog Z80: * FAZE Z80 emulation core by Fox68k * NeoGeo CD Video Display Processor: * Overclock & Underclock Options for both CPUs * Custom PowerVR2 based engine by Chui (sdl_gp32 -at- yahoo.es) * Tile caching. * SQ data transfer. * Optional bilinear filtering * YM2610 FM sound emulation. * Disc Swap with your ROM disc [[Image:Aerofight.gif| Aero Fighters]] [[Image:Artfight.gif| Art of Fighting]] ===NeoGeoCD=== There's also a fork of this emulator that plays NeoGeoCD games called [[NEO4ALL]]. ==Downloads== * Aes4all Beta 2 - [http://chui.dcemu.co.uk/releases/aes4all-beta2-fix.rar Plainfiles] - 04/04/2007 * Aes4all Beta 1 - [http://chui.dcemu.co.uk/releases/neo4all_aes-beta1.rar Plainfiles] - ''Unknown release date ==Burning== ===Needed BIOS Files=== The emulator needs pre-converted AES files that contain portions of the AES BIOS to work. So in order to convert your MVS ROMs for Neo4All/AES, you need to search for these files at first: * aes-bios.bin (128KByte) * ng-lo.rom (64KByte) * ng-sfix.rom (128KByte) * sfix.sfx (128KByte) Google for "Neo Geo BIOS" and once you got the different BIOS distributions that are floating around, unzip them and copy the files listed above into your /NEO4ALL_AES-ALPHA/WINDOWS/CONVERTNEO/BIOS/ folder. Once you found "NG-SFIX.ROM" (128k), simply rename it to "SFIX.SFX". Pay attention to the ROM size! There are TWO DIFFERENT versions of "NG-LO.ROM", one is 128KByte in size, the other 64KByte. The 64KByte version is needed here. InsaneDavid posted this over at DCEmulation.org: Most of the time in a NeoGeo BIOS package if "ng-lo.rom" is present it will be the 128KByte version. However if there isn't present, a 64KByte file called "000-lo.lo" usually is. "000-lo.lo" is the 64KByte version of "ng-lo.rom" - simply rename it to "ng-lo.rom" and you've got what you need. ====Uni-BIOS==== If you are not able for whatever reasons to find the proper "AES-BIOS.BIN", you could try to google for the Uni-BIOS. Rename "UNI-BIOS.ROM" to "AES-BIOS.BIN" and put it along with the other BIOS files in your /NEO4ALL_AES-ALPHA/WINDOWS/CONVERTNEO/BIOS/ folder. Then convert your games. Note that only Uni-BIOS v1.2 will work with the Dreamcast version of Neo4All/AES. Thanks to SUPNEO for the info. ===How To Build A Selfbootable Neo4ALL/AES Disc=== Building a selfbootable disc of Neo4All/AES is the same as with all Dreamcast games or emus. It can be done easily with the available selboot apps like Dir2Boot, Selfboot or SBInducer (where you'd simply have put all files in the /Inducer/ folder). Suggested is BootDreams by fackue as it's by far the best selfboot app. You can get it from here: http://www.dchelp.dcemulation.org/ Just point BootDreams to the folder that's containing Neo4All's 1ST_READ.BIN file and your games. Here's the complete needed disc structure that folder should hold: * ../Neo4AES/1st_read.bin (the emulator itself) * ../Neo4AES/mslugx.aes (your converted games) * ../Neo4AES/NEO4ALL/ (folder) An IP.BIN is not needed if you use BootDreams as it will create the file automatically for you! In general, all IP.BINs are identical so if you don't use BootDreams, just copy that file from any other game or emu. The /NEO4ALL/ folder contains a lot of files like "AES.mod", "Background0.bmp", etc. Some of these are not necessary and could as well be deleted. In fact, deleting them will also free some valuable Kbytes of the DC's RAM and thus improving the performance a lot by definitly reducing the loading times noticably (e.g. SNK vs Capcom, Metal Slug X, etc.), so it's really suggested to delete all unneccessary files. Here's a complete list of all of those files that are needed for the emu to work, so they better should not be deleted: * Background_AES.bmp * Beep.wav * Colors.txt * Loading.bmp * Memcard.bin * Patch.prg * Splash_AES.bmp * Startup.bin * Text.bmp * Text2.bmp * Window.bmp ==Links== * [http://www.dreamcast-scene.com/index.php/Main/AESRecommendGames Recommended AES Games] [[Category:Emulator]] 7ecb57953144104199b6b8b0b2c75951e813a999 NeoCD/SDL DC 0 865 2017 2023-03-01T20:32:26Z Unknown user 0 Created page with "Developer: Ian Micheal Updated: 18-05-04 A very cool port of the Neo Geo CD emulator NEOCD/SDL [http://www.dcemulation.org/phpBB/viewtopic.php?p=518878#518878 NeoGeoCD/SD..." wikitext text/x-wiki Developer: Ian Micheal Updated: 18-05-04 A very cool port of the Neo Geo CD emulator NEOCD/SDL [http://www.dcemulation.org/phpBB/viewtopic.php?p=518878#518878 NeoGeoCD/SDL V7 Game Testing Topic] Dreamcast Port Credits: [[Ian Micheal]], [[Fosters]], Troy "[[GPF]]" Davis, [[BlackAura]], [[BlueCrab]] CREDITS -------------------------------- Fabrice Martinez - The original NeoCD emulator Fosters - SDL port Caz - For the BeOS NeoCD/SDL build Karl Stenerud - The Musashi M680x0 emulator Neil Bradley (neil@synthcom.com) - Multi-Z80 CPU emulator Tatsuyuki Satoh - YM2610 Mame core Derek Liauw Kie Fa. - 2xSaI engine Sam Lantinga (et al) - Simple DirectMedia Layer Quzar- Region selector, frameskip, frame limiting, auto loading, many bugfixes and optimizations. Mekanizer - proper vmu display [http://www.dcemulation.org/files/emulators/V7bin.rar Plain Files] [http://www.dcemulation.org/files/emulators/V7.rar Source] 152ae73df99dc0dedf1377ef5dd2dc0b6f7c3b64 File:Samsho1.gif 6 866 2018 2023-03-01T20:33:25Z Unknown user 0 wikitext text/x-wiki Samsho1 85fb00bec88b012d4320d5af098d5e5a1e1fb484 NeoDC 0 867 2019 2023-03-01T20:33:29Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NeoDC |- border="0" cellpadding="2" cellspacing="1" ali..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NeoDC |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:samsho1.gif| Samurai Shodown]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.screamcast.net/ Homepage]<br/>''(Defunct Domain)}}} |- style="background:#ffffff" |Latest Version || {{{version|v2.3}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/emulators/neodc/NeoDC_scrambled.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/04/05}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://pacifi3d.retrogames.com/neocdsdl/ NeoCD/SDL]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|Neo-Geo CD}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|No}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== NeoCD is the name of the original Neo Geo CD emulator by Fabrice Martinez. NeoCD/SDL was a port of Neo Geo CD to the SDL library. The Dreamcast port, originally known as NeoCD/SDL DC, was a joint effort by [[Quzar]], Fosters, [[BlueCrab]], [[GPF]], [[Ian Micheal]], and [[BlackAura]]. After version 9.1, the emulator was rewritten to use [[KallistiOS]] directly instead of SDL, and was renamed NeoDC. The overall aim of NeoDC was to be independent from SDL, be fullspeed, have full sound effects, and have full CDDA CD track streaming support. NeoDC was voted as the best emulator of 2004 by [http://www.dcemu.co.uk/ DCEmu], and is definately not something to be missed by any Dreamcast owner. ==Downloads== * NeoDC v2.3 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDC_scrambled.rar Plainfiles] ''(fixed)'' - 04/12/05 * NeoDC v2.3 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDCv2.3src.zip Source] - 04/10/05 * NeoDC v2.2 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDCv2.2.zip Plainfiles] - 02/25/05 * NeoDC v2.2 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDCv2.2src.zip Source] - 02/25/05 ==Links== * [http://www.dreamcast-scene.com/index.php/Main/CompatibilityList Dreamcast-Scene Playability List] * [http://web.archive.org/web/20080507055905/http://www.screamcast.net/boards/viewtopic.php?t=152 Official Compatibility List ''(Archived)] * [http://web.archive.org/web/20080528233720/screamcast.net/boards/viewtopic.php?t=172 Screamcast NeoDC Page ''(Archived)] b25592df48972628156c2decedf4d3d1a779d064 2020 2019 2023-03-01T20:33:38Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NeoDC |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:samsho1.gif| Samurai Shodown]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.screamcast.net/ Homepage]<br/>''(Defunct Domain)}}} |- style="background:#ffffff" |Latest Version || {{{version|v2.3}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/emulators/neodc/NeoDC_scrambled.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/04/05}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://pacifi3d.retrogames.com/neocdsdl/ NeoCD/SDL]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|Neo-Geo CD}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|No}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== NeoCD is the name of the original Neo Geo CD emulator by Fabrice Martinez. NeoCD/SDL was a port of Neo Geo CD to the SDL library. The Dreamcast port, originally known as NeoCD/SDL DC, was a joint effort by [[Quzar]], Fosters, [[BlueCrab]], [[GPF]], [[Ian Micheal]], and [[BlackAura]]. After version 9.1, the emulator was rewritten to use [[KallistiOS]] directly instead of SDL, and was renamed NeoDC. The overall aim of NeoDC was to be independent from SDL, be fullspeed, have full sound effects, and have full CDDA CD track streaming support. NeoDC was voted as the best emulator of 2004 by [http://www.dcemu.co.uk/ DCEmu], and is definately not something to be missed by any Dreamcast owner. ==Downloads== * NeoDC v2.3 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDC_scrambled.rar Plainfiles] ''(fixed)'' - 04/12/05 * NeoDC v2.3 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDCv2.3src.zip Source] - 04/10/05 * NeoDC v2.2 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDCv2.2.zip Plainfiles] - 02/25/05 * NeoDC v2.2 - [http://dcemulation.org/1-newsdump/emulators/neodc/NeoDCv2.2src.zip Source] - 02/25/05 ==Links== * [http://www.dreamcast-scene.com/index.php/Main/CompatibilityList Dreamcast-Scene Playability List] * [http://web.archive.org/web/20080507055905/http://www.screamcast.net/boards/viewtopic.php?t=152 Official Compatibility List ''(Archived)] * [http://web.archive.org/web/20080528233720/screamcast.net/boards/viewtopic.php?t=172 Screamcast NeoDC Page ''(Archived)] f377b863e4883fc9eb54bf03db29e9b912a7567f NEO4All 0 868 2021 2023-03-01T20:35:38Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NEO4ALL |- border="0" cellpadding="2" cellspacing="1" a..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NEO4ALL |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:neo4all.png|thumb|280px| Metal Slug 2]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://chui.dcemu.co.uk/index.html Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Release<br/>Candidate 3}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://chui.dcemu.co.uk/releases/neo4all-rc3.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/04/2007}}} |- style="background:#ffffff" |Author || {{{author|[[Chui]]}}} |- style="background:#ffffff" |Based on || {{{original|[[NeoCD/SDL_DC|NeoCD DC]]/<br/>[http://gngeo.berlios.de/ GnGeo]/<br/>[http://pacifi3d.retrogames.com/neocdsdl/index.html NeoCD/SDL]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|NeoGeoCD}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|''Unknown''}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50/60Hz}}} |} ==History== Neo4All is an open-source NeoGeoCD emulator for Dreamcast brought to you by [[Chui]] and [[Fox68k]], and it's by far the best NeoGeoCD emulator for Dreamcast. Using code from the GnGeo project, it's a port of Fabrice Martinez' NeoCD emulator to the Dreamcast based on Fosters' NeoCD/SDL. The current release features amazing compatibility and full speed emulation with full CDDA and SFX. It has a brandnew GUI with customizable controls and even a standalone CD option (so you can burn the emulator and your game to 1 disc). [[Image:Artfight.gif| Art of Fighting]] ===Features=== * Full Speed Emulation * High Compatibility * Disc Swap with NeoGeoCD games ''(rips) * Full VMU Support * Region Selection * 2 Player Support * Nice GUI with Music * Customizable Controls * Safe Reset Function * Standalone CD Feature (the emu + your game on 1 CD) * Low level CD-ROM access for fast CD swap * Main CPU Motorola 68000 * FAME emulation library by Fox68k * Sound CPU Zilog Z80 * FAZE Z80 emulation core by Fox68k * Overclock & Underclock Options for both CPUs * NeoGeo CD Video Display Processor * Custom PowerVR2 based engine by Chui * Tile caching. * SQ data transfer. * Optional bilinear filtering * YM2610 FM sound emulation. [[Image:Puzzbob.gif| Puzzle Bobble]] [[Image:Aerofight.gif| Aero Fighters]] ===To be implemented=== * Arcade Stick (C+Z) support * Button config for menu options. * Ability to read Official Neo CD disks as opposed to rips. * Increased CDDA compatibility ===NeoGeo AES/MVS=== There's also a fork of this emulator that plays AES/MVS cartridge games called [[AES4ALL]] ''(a.k.a. NEO4ALL/AES)''. ==Downloads== * Neo4all RC-3 - [http://chui.dcemu.co.uk/releases/neo4all-rc3.rar Plainfiles] - 04/04/2007 * Neo4all RC-3 - [http://chui.dcemu.co.uk/releases/neo4all-src-rc3-fix.tar.bz2 Source] - 04/04/2007 * Neo4all RC-1 - [http://chui.dcemu.co.uk/releases/neo4all-rc1.rar Plainfiles] - 09/03/2006 * Neo4all RC-1 - [http://chui.dcemu.co.uk/releases/neo4all-src-rc1.tar.bz2 Source] - 09/03/2006 ==Burning== All you need is to have the NeoGeoCD BIOS (NEOCD.BIN, 512 KByte ''- not provided'' ) in your root folder (along with the emulator itself of course): * C:\BootDreams\Neo4All\NEOCD.BIN\ if using [[BootDreams]] or * C:\Sbinducr\Inducer\NEOCD.BIN\ if using [[Selfboot Inducer]] That's it. ==Links== * [http://chui.dcemu.co.uk/ Chui's Site] * [http://www.m68k.com/fame/ FAME Site] ==Compatibility== ''The following games have been reported to work (As standalone game/emulator single discs): * 2020 Super Baseball * 3 Count Bout * Aero Fighters 2 * Aggressors of Dark Kombat * Alpha Mission 2 * Art of Fighting 2 * Baseball Stars 2 * Baseball Stars Professional * Blues Journey * Breakers * Crossed Swords * Crossed Swords 2 * Cyber Lip * Drift Out * Fatal Fury * Football Frenzy * Galaxy Fight * Ghost Pilots * Ironclad * Kabuki Klash * King Of Fighters 94 * King Of Fighters 95 * King of Fighters 96 * King of Fighters 97 * King of Fighters 98 * King of Fighters 99 * Last Hope * League Bowling * Magical Drop 2 * Magician Lord * Master of Syougi * Metal Slug * Metal Slug 2 * Nam 1975 * Neo Turf Masters * Ninja Commando * Ninja Master's * Pulstar * Puzzle Bobble * Quest of Jongmaster * Quiz King of Fighters * Ragnagard * Rally Chase * Real Bout Fatal Fury * Robo Army * Samurai Shodown II * Samurai Shodown IV * Sengoku * Sengoku 2 * Soccer Brawl * Street Slam * Super Sidekicks 2 * Super Spy * Top Hunter * Top Players Golf * Twinkle Starsprites * ViewPoint * Windjammers * World Heroes * World Heroes 2 Jet * World Heroes Perfect * Zintrick [[Category:Emulator]] 90332f70ab475f606c400b1f46aaf57955e7e41b PCSX-DC 0 869 2023 2023-03-01T20:38:12Z Unknown user 0 Created page with "== PCSX-DC == {{Infobox_Emulator_Information| name=PCSX-DC| image=no image| homepage=[http://www.pcsx.net/ Homepage]| version=1.4| downloads=[http://dcemulation.com/1-ne..." wikitext text/x-wiki == PCSX-DC == {{Infobox_Emulator_Information| name=PCSX-DC| image=no image| homepage=[http://www.pcsx.net/ Homepage]| version=1.4| downloads=[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-DJ.zip DiscJuggler (NTSC)]<br/>[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-DJ.zip DiscJuggler (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-Nero.zip Nero (NTSC)]<br/ >[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-Nero.zip Nero (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-Plain-NTSC.zip Plain Files (NTSC)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-PlainFiles.zip Plain Files (PAL)]<br />| release date=10/31/2002| author=[[Mark Grilenkov]]| original=PCSX<br/>(PCSX-Team)| systems=PlayStation| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} PCSX-DC is the first homebrew Playstation emulator for the Dreamcast and shows that large scale PlayStation emulation on Dreamcast IS possible. It is a port of the popular PC PlayStation emulator PCSX. Right now speeds are not playable and there is no sound. However it is a great proof of concept. The Dreamcast port of PCSX was done by [[Mark Grilenkov]]. ==Features== *Supports .bin image files (This is the only thing it supports) *Built in HLE bios (Official Sony bios also supported) *PAL and NTSC support 0b261150dad88fc14a68967dd1620852577508ac PCSX WIP 0 870 2024 2023-03-01T20:38:35Z Unknown user 0 Created page with "Developer: Ian Micheal Updated: 2003 A Playstation emulator that runs Ridge Racer at 10 frames per second Speed: 10 FPS Sound: [http://www.dcemulation.org/phpBB/vie..." wikitext text/x-wiki Developer: Ian Micheal Updated: 2003 A Playstation emulator that runs Ridge Racer at 10 frames per second Speed: 10 FPS Sound: [http://www.dcemulation.org/phpBB/viewtopic.php?t=36828 pcsx wip 1.5] [http://www.dcemulation.org/files/emulators/pcsx1.5wip.zip Plain Files] [http://www.dcemulation.org/files/sbi3.0/SBI-pcsx1.5wip.sbi Selfboot Inducer] =Other page= Developer: Ian Micheal Updated: 16-02-04 Better fullscreen mode, runs more games 2d games are playable but slow as before. But it is a bit smoother. About 10 fps [http://www.dcemulation.org/files/emulators/1_5wip4.rar Plain Files] 22fdced55198a07a68e9607e95db15cd67edb770 File:Bleem-rr4 dc detail.gif 6 871 2025 2023-03-01T20:39:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Bleem-rr4 dc detail}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e103bd257f891c1bf23a891c06f799aa4ed39af4 File:Bleem-rr4 psx detail.gif 6 872 2026 2023-03-01T20:39:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Bleem-rr4 psx detail}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 03290ba0213597d62bf5bf227ef33807ce75c103 File:Bleemcast.jpg 6 873 2027 2023-03-01T20:39:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Bleemcast}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 415c95988c341cfa3097e5ad3e2070cddeee7244 Bleemcast! 0 874 2028 2023-03-01T20:39:55Z Unknown user 0 Created page with "[[Image:bleem-rr4_psx_detail.gif|thumb|Ridge Racer on a real PlayStation]] [[Image:bleem-rr4_dc_detail.gif|thumb|Ridge Racer in bleemcast!]] Image:bleemcast.jpg|thumb|rgiht|..." wikitext text/x-wiki [[Image:bleem-rr4_psx_detail.gif|thumb|Ridge Racer on a real PlayStation]] [[Image:bleem-rr4_dc_detail.gif|thumb|Ridge Racer in bleemcast!]] [[Image:bleemcast.jpg|thumb|rgiht|bleemcast!]] bleemcast! is a commercial PlayStation 1 emulator for Dreamcast by [http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&sid=4021c15247a8129d224543722691686b&u=4493 Rand Linden] and [http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=14203 Rod Maher]. (Both were active members in the DCEmulation forum) It is not a port of the original bleem! emulator, but a completely new code base. bleemcast! improves the quality of the orginial PSX games since they run in 640x480 in bleemcast! (320x240 on a real PSX). bleem!cast was purely written in SH4 assembler. There were three official releases, each of them emulates the PlayStation 1 games they were made for: Gran Turismo 2, Tekken 3 and Metal Gear Solid. Please see the [[bleemcast! FAQ]] for more information. DCEmulation hosted a bleemcast! forum that was frequented by the bleemcast! team, who often posted information and answered users' questions. It has been closed since bleem! folded, but the forum and all of its useful information can still be viewed [http://dcemulation.org/phpBB/viewforum.php?f=25 here]. == Features == *Smooth, 640x480 3D graphics from original PlayStation-1 games (even the PS2 can't do that!) *Clean, filtered textures (you can actually READ every sign you pass at 180mph) *Full-screen anti-aliasing for added realism (no more "jaggies"!). *Save & load games to regular Dreamcast VMUs (requires dedicated VMU) *PAL Extended - no borders on PAL TVs! *Compatible with VGA boxes *Jump-Pack vibration support ==bleem!cast beta== There is a leaked beta version of bleemcast! that has made its way across the internet. This beta is capable of playing many PlayStation games although not anywhere near the same level as the commercial releases do. Many games do run but not all of them are really playable. The beta lacks saving capabilities and FMVs aren't supported, so many games whose storylines depend on FMVs or long games that require saving aren't playable at all. The authors have [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=29658 commented on the forums] about the state of the emulator's beta version and their feelings on the leak. [http://web.archive.org/web/20010515082508/http://www.bleem.com/ Bleem.com@Archive.org] http://dcemulation.org/legacy/pay-bleemcast.htm 6f500e3022d0f431199fcee0683816e3779b79ba File:Funvision.jpg 6 875 2029 2023-03-01T20:40:48Z Unknown user 0 wikitext text/x-wiki Funvision f9510b9e935488a316b5d3de73d879ea3570c2a8 FunnyMu 0 876 2030 2023-03-01T20:40:51Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | FunnyMu |- border="0" cellpadding="2" cellspacing="1" a..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | FunnyMu |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Funvision.jpg| Funvision]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://imrtechnology.ngemu.com/downloads/fun_binscr.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[Ian Micheal]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://www.lemoncube.com/26.html FunnyMu]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|Whizzard/<br/>Funvision/<br/>Creativision}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== This is a port of the SDL Funvision emulator FunnyMu to the Dreamcast. 'FunnyMu' is an emulator of the Whizzard, Funvision and Creativision computer/games consoles that were sold in the early 1980s. The VTech Creativision was distributed in Europe (Italy, Sweden and Germany for sure) and South Africa. However it was also marketed in other countries and called the "Dick Smith Wizzard", "FunVision Computer Video Games System" and "Hanimex Rameses". The Wizzard may have been a licensed version for the Australian market since Dick Smith Industries maintained the VTech logo, but the others most likely were clones. The FunVision had a slight alteration that made the carts and cartridge slot larger. ==Downloads== * FunnyMu - [http://imrtechnology.ngemu.com/downloads/fun_binscr.rar Plainfiles], [http://dreamcast.dcemu.co.uk/fun_binscr.rar Alt.] - ''Unknown release date * FunnyMu - [http://imrtechnology.ngemu.com/downloads/funvision_cdi.rar CDI Image] - ''Unknown release date * FunnyMu - [http://imrtechnology.ngemu.com/downloads/fun_src.rar Source] - ''Unknown release date 468872c6039aa22234382fa1b362a74677f6acb6 2031 2030 2023-03-01T20:40:59Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | FunnyMu |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Funvision.jpg| Funvision]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://imrtechnology.ngemu.com/downloads/fun_binscr.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[Ian Micheal]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://www.lemoncube.com/26.html FunnyMu]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|Whizzard/<br/>Funvision/<br/>Creativision}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== This is a port of the SDL Funvision emulator FunnyMu to the Dreamcast. 'FunnyMu' is an emulator of the Whizzard, Funvision and Creativision computer/games consoles that were sold in the early 1980s. The VTech Creativision was distributed in Europe (Italy, Sweden and Germany for sure) and South Africa. However it was also marketed in other countries and called the "Dick Smith Wizzard", "FunVision Computer Video Games System" and "Hanimex Rameses". The Wizzard may have been a licensed version for the Australian market since Dick Smith Industries maintained the VTech logo, but the others most likely were clones. The FunVision had a slight alteration that made the carts and cartridge slot larger. ==Downloads== * FunnyMu - [http://imrtechnology.ngemu.com/downloads/fun_binscr.rar Plainfiles], [http://dreamcast.dcemu.co.uk/fun_binscr.rar Alt.] - ''Unknown release date * FunnyMu - [http://imrtechnology.ngemu.com/downloads/funvision_cdi.rar CDI Image] - ''Unknown release date * FunnyMu - [http://imrtechnology.ngemu.com/downloads/fun_src.rar Source] - ''Unknown release date 4379877c9a7ef89e1af1ecd97cada012c3362c72 Template:Infobox Tools Information 10 877 2032 2023-03-01T20:51:22Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|<i>No Screenshot Available</i>}}} |- style="background:#ffffff" |Homepage || {{{homepage|<i>Unknown</i>}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|<i>Unknown</i>}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |} 041480beb9b6e2c541ef4ab5b8c8ee854d804f6c File:Bootdreams.jpg 6 878 2033 2023-03-01T20:51:41Z Unknown user 0 wikitext text/x-wiki Bootdreams 1428fa3e29d5d4f9d5fbd7dacb8b47162ade44bb BootDreams 0 879 2034 2023-03-01T20:51:46Z Unknown user 0 Created page with "{{Infobox_Tools_Information| name=BootDreams| image=[[Image:Bootdreams.jpg|center|250px]]| homepage=[https://code.google.com/archive/p/bootdreams/ Homepage]| version=1.0.6..." wikitext text/x-wiki {{Infobox_Tools_Information| name=BootDreams| image=[[Image:Bootdreams.jpg|center|250px]]| homepage=[https://code.google.com/archive/p/bootdreams/ Homepage]| version=1.0.6c| downloads=[https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/bootdreams/bootdreams_106c.exe Binary]<br />[https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/bootdreams/bootdreams_106c_src.zip Source]| release date=4/04/2008| author=fackue| isactive=No }} This tool uses [[CDI4DC]] by [[SiZiOUS]] to create [[selfboot|selfbooting]] CDI images. It currently supports the following features: injecting an [[MR logo]] into an [[IP.BIN]] before creating the CDI image, automatic [[Dummy file]] calculations for a specified CD-R size and much, much more. bcd28ca4427597d1fca213f468cfcd30e5414822 BurgerDC 0 880 2035 2023-03-01T21:01:36Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | BurgerDC |- style="background:#ffffff" |Homepage || {{{..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | BurgerDC |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcevolution.sourceforge.net/index.php?id=the_sandman_volume_1 The Sandman Volume 1]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Warmtoe}}}, {{{author|Krut}}}, {{{author|DaMadFiddler}}}, <br>{{{author|MetaFox}}} |- style="background:#ffffff" |Type of game || {{{type|BurgerTime Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== ''Burger DC'' was created and programmed by [[Warmtoe]], with music by [[DaMadFiddler]], and art by [[Krut]] and [[MetaFox]]. ==Downloads== * ''Version 2'' - [http://dcevolution.sourceforge.net/index.php?id=the_sandman_volume_1 The Sandman Volume 1] - ''December 24, 2006'' 268799f6f6e86027dc9051543816ae85404c4c3c Freeware homebrew games 0 76 2036 975 2023-03-01T21:01:58Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Space Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[ArmoredCampaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[SonicRoboBlast2|Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 50c6dbd7bb21f207aa67570f5826c82545b02286 CloneKeen 0 881 2037 2023-03-01T21:02:04Z Unknown user 0 Created page with "CloneKeen is an open-source clone of ID's classic DOS game Commander Keen. CloneKeen runs under many platforms including Linux & win32. There are some improvements over the or..." wikitext text/x-wiki CloneKeen is an open-source clone of ID's classic DOS game Commander Keen. CloneKeen runs under many platforms including Linux & win32. There are some improvements over the original such as 2-player support. Original game data files are required. A Dreamcast port is available. [[File:CloneKeenDC.rar|CloneKeen Dreamcast binary]] [[File:CloneKeenSrc.rar|CloneKeen Dreamcast source]] add872b4e2c8cec0d92ac20ea0687d81ccecd7cb File:License.gif 6 884 2040 2023-03-01T21:06:02Z Unknown user 0 wikitext text/x-wiki IP.BIN License Screen 8bde60331da7044c1bc696749163d8e5c6831d5c IP.BIN 0 35 2041 714 2023-03-01T21:07:07Z Unknown user 0 wikitext text/x-wiki [[File:License.gif|thumb|What the player sees during IP.BIN execution, with a Windows CE MR logo displayed]] The Dreamcast bootsector (commonly named '''IP.BIN''') is placed on a [[GD-ROM]] or a [[MIL-CD]] in the first 16 sectors of the data track from which the Dreamcast is booting. It contains information about the software on the disc, including [[region protection]], as well as the code that displays the Sega copyright screen and prepares the system for the launch of a game title. Originally the bootsector was lifted from Dreamcast games to boot homebrew software, but technically using this copyrighted code was illegal in some jurisdictions. Homebrew coder [[LiENUS]] originally [[LiENUS's IP.BIN|rewrote the IP.BIN file]], replacing as much as possible with free code. The only code that remains in this homebrew IP.BIN is Sega's copyright screen code, which is required to be unmodified in order for the disc to boot (the system checks it against a copy of the code held within the BIOS ROM). It is believed by some that using this last bit of code is legal due to the legal precedent set by ''[http://digital-law-online.info/cases/24PQ2D1561.htm Sega v. Accolade]''. New, additional functionality has been added to the IP.BIN in the [[neoIP]] replacement IP.BIN project. It is currently able to load homebrew and official Katana or Windows CE binaries from either [[GD-ROM]] or [[CD-ROM]]. == Basic Overview == * Loaded and ran from Disc ([[GD-ROM]], [[CD-ROM]]) * Contains basic meta information for a disc * Draws the Sega License Screen * Possibly holds an [[MR Image]] * Has space to run Code that is typically used in setting up the basic hardware then launching the binary on disc == General Header Information == Overview of Each piece of the IP.BIN listing file offset and memory location when loaded <ref>''[http://mc.pp.se/dc/ip.bin.html]'', Dreamcast Programming: IP.BIN, Marcus Comstedt</ref> {| class="wikitable" !Offset !Size !Load address !Contents |- |0x0000-00FF |0x00FF : 256 Bytes |8C008000-8C0080FF |Meta information |- |0x0100-02FF |0x01FF : 512 Bytes |8C008100-8C0082FF |Table of contents |- |0x0300-36FF |0x33FF : 13312 Bytes |8C008300-8C00B6FF |SEGA license screen code |- |0x3700-37FF |0x00FF : 256 Bytes |8C00B700-8C00B7FF |Area protection symbols |- |0x3800-5FFF |rowspan="2"|0x47FF : 18432 Bytes |8C00B800-8C00DFFF |Bootstrap 1 |- |0x6000-7FFF |8C00E000-8C00FFFF |Bootstrap 2 (Not Required [[#Bootstraps]]) |} === Meta information === {| class="wikitable" !Offset !Contents |- |000-00F |Hardware ID (always "SEGA SEGAKATANA ") |- |010-01F |Maker ID (always "SEGA ENTERPRISES") |- |020-02F |Device Information (see below) |- |030-037 |Area Symbols (see below) |- |038-03F |Peripherals (see below) |- |040-049 |Product number ("HDR-nnnn" etc.) |- |04A-04F |Product version |- |050-05F |Release date (YYYYMMDD) |- |060-06F |Boot filename (usually "1ST_READ.BIN") |- |070-07F |Name of the company that produced the disc |- |080-0FF |Name of the software |} == Execution Flow Overview == bleh == Deeper Look into User Code == All IP.BIN files from Sega are generally made with the IP Maker software and follow the same basic layout codewise. Bootstrap 1 is very small and is responsible for setting some minor hardware registers then jumps immediately to Bootstrap 2. This second Bootstrap actually does the bulk of the work and handles setting up the stack, VBR, disables cpu caching and then handles the jump to [[1ST_READ.BIN]] which is loaded to address 0x8C010000. === Bootstraps === This is the area in the IP.BIN that is completely unregulated and can be used however someone would like. ==== Bootstrap 1 ==== This piece of code is generally very small, under 32 bytes and sets hardware registers. * A custom [[MR Image]] can also live within this section at offset 0x3820, Address 0x8C00B820 and will be displayed on the license screen. ==== Bootstrap 2 ==== This is Generally where all the base setup code is kept so our binary has a known, and clean execution environment in which it starts. In [[Warez]] releases this is the area that is responsible for a very sneaky trick. The [[1ST_READ.BIN]] binary is kept as is on the disc, but then when scramble loaded by the bios (See [[Dreamcast_Boot_Process]] for further)) it will be unusable, so code was written to unscramble, the now ruined binary, in-place. The second part of this trick also reinitializes the [[GD-ROM]] drive and passes the [[HOLLY]] bios check so that the game may access the data on the disc and execute normally. ==References== <references/> 9e3cd50044374fba2c66069edd7d5d5f5f74bb55 File:Mamedc5.jpg 6 885 2042 2023-03-01T21:20:10Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc5}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 281fdcce8e06010cef0c8de338661bef2a4f4bcd File:Mamedc6.jpg 6 886 2043 2023-03-01T21:20:10Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc6}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 35d393a4eecf30dfbcfe0447fe474ece330126c1 File:Mamedc8.jpg 6 887 2044 2023-03-01T21:20:10Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc8}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 81d2a630967a5a509adc83bb14127e4ee5bfcbe2 MamedDC 0 888 2045 2023-03-01T21:20:16Z Unknown user 0 Created page with "Developer: MAMED Version: Beta 1 Last Updated: 07-17-01 MAMEDDC is an attempt to port MAME to the (wonderful) Dreamcast console by the same author who has ported it to m..." wikitext text/x-wiki Developer: MAMED Version: Beta 1 Last Updated: 07-17-01 MAMEDDC is an attempt to port MAME to the (wonderful) Dreamcast console by the same author who has ported it to many devices. Status: * Hundreds Of Games Supported * Sound Screen Shots: [[Image:Mamedc8.jpg]] [[Image:Mamedc6.jpg]] [[Image:Mamedc5.jpg]] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedkit.zip Mamed Kit] A kit to help you burned these mamed's. [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed1.rar DiskJuggler 1] MAMED Game Pack 1 ([http://dcemulation.org/files/emulators/mamed/gamelist1.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed2rar DiskJuggler 2] MAMED Game Pack 2 ([http://dcemulation.org/files/emulators/mamed/gamelist2.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed3.rar DiskJuggler 3] MAMED Game Pack 3 ([http://dcemulation.org/files/emulators/mamed/gamelist3.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed4.rar DiskJuggler 4] MAMED Game Pack 4 ([http://dcemulation.org/files/emulators/mamed/gamelist4.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed5.rar DiskJuggler 5] MAMED Game Pack 5 ([http://dcemulation.org/files/emulators/mamed/gamelist5.txt Games Supported]) (Games not Included) DiskJuggler 6 MAMED Game Pack 6 ([http://dcemulation.org/files/emulators/mamed/gamelist6.txt Games Supported]) (Games not Included) DiskJuggler 7 MAMED Game Pack 7 ([http://dcemulation.org/files/emulators/mamed/gamelist7.txt Games Supported]) (Games not Included) DiskJuggler 8 MAMED Game Pack 8 ([http://dcemulation.org/files/emulators/mamed/gamelist8.txt Games Supported]) (Games not Included) DiskJuggler 9 MAMED Game Pack 9 ([http://dcemulation.org/files/emulators/mamed/gamelist9.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed10.rar DiskJuggler 10] MAMED Game Pack 10 ([http://dcemulation.org/files/emulators/mamed/gamelist10.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed11.rar DiskJuggler 11] MAMED Game Pack 11 ([http://dcemulation.org/files/emulators/mamed/gamelist11.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed12.rar DiskJuggler 12] MAMED Game Pack 12 ([http://dcemulation.org/files/emulators/mamed/gamelist12.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed13.rar DiskJuggler 13] MAMED Game Pack 13 ([http://dcemulation.org/files/emulators/mamed/gamelist13.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed14.rar DiskJuggler 14] MAMED Game Pack 14 ([http://dcemulation.org/files/emulators/mamed/gamelist14.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed15.rar DiskJuggler 15] MAMED Game Pack 15 ([http://dcemulation.org/files/emulators/mamed/gamelist15.txt Games Supported]) (Games not Included) 857088c0ca86f11e23866ca0c6396adfdbbbe3d6 File:Mamedc2.jpg 6 890 2046 2023-03-01T21:23:01Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc2}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d61627600bf396c05dbaf81703ae7a9fce80608e File:Mamedc.jpg 6 889 2047 2023-03-01T21:23:01Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 47fd5e8352ed2a259e7ab091ef4678c3b1432bc9 File:Mamedc3.jpg 6 891 2048 2023-03-01T21:23:01Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc3}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 81e18b1096555799f4afdf72eee658967544ada7 File:Mamedc4.jpg 6 892 2049 2023-03-01T21:23:01Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mamedc4}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c645dc99e271a8b2bc74c98a20749806903e9d5b MameDC 0 893 2050 2023-03-01T21:23:13Z Unknown user 0 Created page with "Developer: Christophe Thibault - Site Version: 0.4 Last Updated: 07-21-01 MAMEDC is an attempt to port MAME to the (wonderful) Dreamcast console. Status: * Some games..." wikitext text/x-wiki Developer: Christophe Thibault - Site Version: 0.4 Last Updated: 07-21-01 MAMEDC is an attempt to port MAME to the (wonderful) Dreamcast console. Status: * Some games work at 100% framerate, others are slower. * Supports the following drivers: PacMan, Arkanoid, Super Qix (bootleg), Psychic5, - Pang and Super Pang. * More drivers work but they are untested for now. * Basic (and buggy) sound support! * VERY unoptimized for now * James Surine provided working sound support! * added Ghosts'n Goblins and Commando drivers * now uses the TA hardware for displaying the screen so it's somewhat faster and looks way better * zip support added but it doesn't work right so keep on using unzipped roms * cd swapping code should be fixed (thanks to James Surine) * James also fixed a small bug in the sound code * zip support fixed! put all your zipped roms in the /roms/ folder * looks like some roms HAVE to be zipped otherwise they won't work * added bubble bobble, bombjack & contra drivers! * second controller support * added double dragon, double dragon 2, mspacman, galaga, 88 games, ikari warriors, gauntlet, gauntlet 2, 1941, ghouls'n ghosts (buggy), final fight (buggy) and strider (buggy) drivers * added gamelist scroll as the game list is getting huge :) * the auto frameskip sucked so it's now manual * more improvements in the graphic code. some drivers (like pang, contra and commando) are noticably faster * added progress indicator when loading roms * added 3rd button (B) support on the controllers * added antialias setting Screen Shots: [[Image:Mamedc.jpg]] [[Image:Mamedc4.jpg]] [[Image:Mamedc3.jpg]] [[Image:Mamedc2.jpg]] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc04-dj.zip Disk Juggler] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc04-nero.zip Nero] [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc04-bin.zip Plain Files] =Old Versions= [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc03-dj.zip Disk Juggler] Version 0.3 [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc03-nero.zip Nero] Version 0.3 [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc03-bin.zip Plain Files] Version 0.3 [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc02-dj.zip Disk Juggler] Version 0.2 [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc02-nero.zip Nero] Version 0.2 [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc02-bin.zip Plain Files] Version 0.2 [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamedc01-dj.zip Disk Juggler] Version 0.1 9880001c08543050e5572df8365e94ab344c6dbc File:Mame4all.png 6 894 2051 2023-03-01T21:24:21Z Unknown user 0 wikitext text/x-wiki Mame4all c4ea22c62d79bed714ad6c21bab8554288a5ad43 File:Mame4allscreen.png 6 895 2052 2023-03-01T21:24:27Z Unknown user 0 wikitext text/x-wiki Mame4allscreen 8e3477fbc7deb626b743ead0f2416c2feb0b6741 MAME4All 0 896 2053 2023-03-01T21:24:32Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=MAME4ALL| image=[[Image:Mame4all.png]]<br /><br />[[Image:Mame4allscreen.png|center|240px]]| homepage=[http://chui.dcemu.co.uk/ Homepag..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=MAME4ALL| image=[[Image:Mame4all.png]]<br /><br />[[Image:Mame4allscreen.png|center|240px]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 1| downloads=[http://dcemulation.org/1-newsdump/emulators/mame4all/mame4all-beta1.rar Plain Files]| release date=March 12th, 2008| author=[[Chui]]| original=[http://mamedev.org/ MAME]| systems=Multiple Arcade Cabinets 80's-90's| best=Yes| refreshrate=50Hz/60Hz| isactive=Unknown }} At the moment, MAME4ALL is beta stage, but hundreds of games work fine. '''Features: *[http://www.talfi.net/gp32_franxis/ MAME GP2X] adaptation to Dreamcast. *FAME Motorola 68000 core. *New FAZE Zilog Z80 core. *Around 1000 games supported. *Split into 3 parts: Aged, Classic and Gold. *Previous menu selection. *Auto-frameskip. *4 players support. *Hardware scaled blitter. *60-50Hz selection for PAL Dreamcasts. *Samples (.sam) support. *Two sound modes: normal and accurate. *CPU speed, sound, and joypad configuration options. *Improved compatibility over previous versions *Uses [http://maws.mameworld.info/maws/ MAME 0.34/0.35] romset like MAME GP2X 5.1, except for NeoGeo. *Uses standard [http://maws.mameworld.info/maws/ MAME naming] for zipped roms. ==Source== *Beta 1 - [http://dcemulation.org/1-newsdump/emulators/mame4all/mame4all-beta1-src.tar.tar Source] - 3/12/08 *Alpha 2 - [http://dcemulation.org/1-newsdump/emulators/mame4all/mame4all-alpha2-src.tar.bz2 Source] - 4/25/06 [[Category:Emulator]] 131d2dae9d03777a898737050049a61c7ddc5b25 2054 2053 2023-03-01T21:24:43Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=MAME4ALL| image=[[File:Mame4all.png]]<br /><br />[[File:Mame4allscreen.png|center|240px]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 1| downloads=[http://dcemulation.org/1-newsdump/emulators/mame4all/mame4all-beta1.rar Plain Files]| release date=March 12th, 2008| author=[[Chui]]| original=[http://mamedev.org/ MAME]| systems=Multiple Arcade Cabinets 80's-90's| best=Yes| refreshrate=50Hz/60Hz| isactive=Unknown }} At the moment, MAME4ALL is beta stage, but hundreds of games work fine. '''Features: *[http://www.talfi.net/gp32_franxis/ MAME GP2X] adaptation to Dreamcast. *FAME Motorola 68000 core. *New FAZE Zilog Z80 core. *Around 1000 games supported. *Split into 3 parts: Aged, Classic and Gold. *Previous menu selection. *Auto-frameskip. *4 players support. *Hardware scaled blitter. *60-50Hz selection for PAL Dreamcasts. *Samples (.sam) support. *Two sound modes: normal and accurate. *CPU speed, sound, and joypad configuration options. *Improved compatibility over previous versions *Uses [http://maws.mameworld.info/maws/ MAME 0.34/0.35] romset like MAME GP2X 5.1, except for NeoGeo. *Uses standard [http://maws.mameworld.info/maws/ MAME naming] for zipped roms. ==Source== *Beta 1 - [http://dcemulation.org/1-newsdump/emulators/mame4all/mame4all-beta1-src.tar.tar Source] - 3/12/08 *Alpha 2 - [http://dcemulation.org/1-newsdump/emulators/mame4all/mame4all-alpha2-src.tar.bz2 Source] - 4/25/06 [[Category:Emulator]] 990a4a669a0e6d236fb97417ac12b91a866f8913 Cpmame 0 897 2055 2023-03-01T21:25:21Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=CPMAME| image=N/A| homepage=[http://siseinohito.tripod.co.jp/ Homepage]| version=???| downloads=[http://www.dcemulation.org/dl/dl.php..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=CPMAME| image=N/A| homepage=[http://siseinohito.tripod.co.jp/ Homepage]| version=???| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/cpmame.zip Plain Files]| release date=Unknown| author=Sisei| original=MAME | systems=MAME| best=No| refreshrate=''Unknown| isactive=''Unknown| }} Unnofficial Mame for DC / CPMAME Developer: Sisei Version: CP1MAME37b16 Last Updated: May, 2002 Description: A port of MAME. =Downloads= * CP1MAME37b16 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/cpmame.zip Plain Files] 779kb [[category:emulator]] f5c3c29c68fe0c6151ef6bde28b98ff36b151906 LaserDC 0 898 2056 2023-03-01T21:26:07Z Unknown user 0 Created page with "Developer: [http://devcast.wolfnet.org/ ss_teven - DevCast] Version: v0.13 r1 Last Updated: 11-01-01 LaserDC is a Midway Z80 Emulator for the Sega Dreamcast console syst..." wikitext text/x-wiki Developer: [http://devcast.wolfnet.org/ ss_teven - DevCast] Version: v0.13 r1 Last Updated: 11-01-01 LaserDC is a Midway Z80 Emulator for the Sega Dreamcast console system. Its currently in beta-stage so bugs do exist. This emulates the following arcade games: * Space Invaders * Space Invaders Deluxe * Lunar Rescue * Galaxy Wars * Space Attack II * Destination Earth * Invaders Revenge * Super Earth Invasion * Boot Hill * Space Invaders (CV Ver) * Cosmic Monsters * Laser * Space King * Check Mate * Space War 3 * Clowns * Space Invaders (TV Version) * 4 Player Bowling Alley * Moon Base * Space Invaders Part II * Lupin III * Space Fever * Space Attack * Space King Part 2 * Test * Star Wars * Space Chaser * Amazing Maze * Ozma Wars * Ozma Wars (set 2) * Solar Fight * Super Invaders * Super Invaders (EMAG) * Super Invaders (Zenitone-Microsec) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/laserdcr1.zip Plain Files] 20b38a33a95e75e700b1c04224ace5516127a9eb System16 0 899 2057 2023-03-01T21:26:30Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | System16 |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | System16 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|''Image<br/>not available''}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://dev.dcemulation.org/mamed/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dev.dcemulation.org/mamed/SYSTEM16_BETA2.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|01/13/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Reaper2K2]]}}} |- style="background:#ffffff" |Based on || {{{original|MAME<br/>''(Unknown version)''}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|System 16 Arcade}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|''Unknown''}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown''}}} |} ==History== This is a port of the System 16 code from MAME. It allows for the emulation of System 16 games on your Dreamcast. ===Features=== * Fullscreen position fixed. * Sound quality improved. * Sound tick, and buzzing, fixed in most games. * Fullspeed without sound. * New games supported. ''(from last ver.)'' ==Downloads== * Beta 2 - [http://dev.dcemulation.org/mamed/SYSTEM16_BETA2.zip Plainfiles] - 10/03/2003 * Beta 1 - [http://dev.dcemulation.org/mamed/SYSTEM16_BETA1.zip Plainfiles] - ''Unknown release date 95f791c071c57a097e4ea04e6d4aa2627d6e1021 File:Marathon2.jpg 6 900 2058 2023-03-01T21:30:52Z Unknown user 0 wikitext text/x-wiki Marathon2 99c5127a30f60fc8e38614617411f1549eea808a Aleph One 0 901 2059 2023-03-01T21:30:59Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aleph One |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aleph One |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Marathon2.jpg|Thumb|250px| Marathon 2: Durandal]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://sdl-dc.sourceforge.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|0.12.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://sourceforge.net/projects/sdl-dc/files/AlephOne/0.12.0-dc-1/AlephOne-0.12.0-dc-1.zip/download Plainfiles]<br />[http://sourceforge.net/projects/sdl-dc/files/AlephOne/0.12.0-dc-1/AlephOne-0.12.0-dc-1-minf.nrg.zip/download Nero Image]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/10/2002 }}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://alephone.cebix.net/ Aleph One/SDL]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Aleph One is an Open Source 3D first-person shooter game, based on the game Marathon 2 by [http://www.bungie.net/ Bungie Software], and was ported to the Dreamcast by [[Bero]]. Unfortunately, the port was left in an early stage, so it doesn't support Dreamcast specific features like ''- joystick control, VMU saving, etc.'' ===Features=== * A keyboard is required to play. * No VMU save support. * The original Marathon 1 data files are not compatible with Aleph One, but Raul Bonilla and the M1A1 team have made an excellent conversion called M1A1. ==Downloads== * Aleph One DC - [http://prdownloads.sourceforge.net/sdl-dc/AlephOne-0.12.0-dc-1.zip Plainfiles] - 10/10/2002 * Aleph One DC - [http://prdownloads.sourceforge.net/sdl-dc/AlephOne-0.12.0-dc-1-minf.nrg.zip Nero Image] - 10/10/2002 * Freeware Game Files ** [http://trilogyrelease.bungie.org/ Official Bungie Page] ** [http://alephone.cebix.net/ Aleph One/SDL Page] (with A1M1 conversion) * Marathon Trilogy Compilation - [http://www.dcevolution.net/index.php?id=marathon_trilogy via Dcevolution] (Ready to burn CDI image) ==Links== * [http://www.bungie.net/ Official Bungie Site] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) aa414c80b54060bdb435bbcfe239a5beb201d663 2060 2059 2023-03-01T21:31:07Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aleph One |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Marathon2.jpg|Thumb|250px| Marathon 2: Durandal]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://sdl-dc.sourceforge.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|0.12.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://sourceforge.net/projects/sdl-dc/files/AlephOne/0.12.0-dc-1/AlephOne-0.12.0-dc-1.zip/download Plainfiles]<br />[http://sourceforge.net/projects/sdl-dc/files/AlephOne/0.12.0-dc-1/AlephOne-0.12.0-dc-1-minf.nrg.zip/download Nero Image]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/10/2002 }}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://alephone.cebix.net/ Aleph One/SDL]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Aleph One is an Open Source 3D first-person shooter game, based on the game Marathon 2 by [http://www.bungie.net/ Bungie Software], and was ported to the Dreamcast by [[Bero]]. Unfortunately, the port was left in an early stage, so it doesn't support Dreamcast specific features like ''- joystick control, VMU saving, etc.'' ===Features=== * A keyboard is required to play. * No VMU save support. * The original Marathon 1 data files are not compatible with Aleph One, but Raul Bonilla and the M1A1 team have made an excellent conversion called M1A1. ==Downloads== * Aleph One DC - [http://prdownloads.sourceforge.net/sdl-dc/AlephOne-0.12.0-dc-1.zip Plainfiles] - 10/10/2002 * Aleph One DC - [http://prdownloads.sourceforge.net/sdl-dc/AlephOne-0.12.0-dc-1-minf.nrg.zip Nero Image] - 10/10/2002 * Freeware Game Files ** [http://trilogyrelease.bungie.org/ Official Bungie Page] ** [http://alephone.cebix.net/ Aleph One/SDL Page] (with A1M1 conversion) * Marathon Trilogy Compilation - [http://www.dcevolution.net/index.php?id=marathon_trilogy via Dcevolution] (Ready to burn CDI image) ==Links== * [http://www.bungie.net/ Official Bungie Site] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) f35356030efc6f251f2eacc97168ab204568fb2c File:3dAsteriods1.jpg 6 902 2061 2023-03-01T21:32:21Z Unknown user 0 wikitext text/x-wiki 3dAsteriods1 4c1ea91843d58403f20d4aedab54b187edeea2fc File:3dAsteriods2.jpg 6 903 2062 2023-03-01T21:32:28Z Unknown user 0 wikitext text/x-wiki 3dAsteriods2 cae3eaabec3269dc11f7445539b4f957c5a96498 3D Asteroids 0 904 2063 2023-03-01T21:32:32Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Asteroids |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Asteroids |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3dAsteriods2.jpg|thumb|300px| 3D Asteroids]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://jimbomania.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|0.0.7}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Jimbo]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:3dAsteriods1.jpg|230px| 3D Asteroids]] ''A 3D version of the arcade classic Asteroids.'' ==Downloads== * dcasteroids-0.0.7 - [http://web.archive.org/web/20061006052027/http://www.dchomebrew.org/zacmcd/Files/asteriods.zip Plainfiles] - 05/06/2002 * dcasteroids-0.0.7 - [http://www.boob.co.uk/files/dcasteroids-0.0.7.nrg Nero Image] - 05/06/2002 * dcasteroids-0.0.7 - [http://www.boob.co.uk/files/dcasteroids-0.0.7.elf Elf] - 05/06/2002 * dcasteroids-0.0.7 - [http://www.boob.co.uk/files/dcasteroids-0.0.7.tar.gz Source] - 05/06/2002 0bf59cd0fa8c7165aa1cb4856cf89ca513d0d24d LynxMESS 0 905 2064 2023-03-01T21:34:52Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=LynxMESS| image=N/A| homepage=Unknown| version=v1| downloads=[http://www.dcemulation.org/files/emulators/lynxdc.zip Plain files]| re..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=LynxMESS| image=N/A| homepage=Unknown| version=v1| downloads=[http://www.dcemulation.org/files/emulators/lynxdc.zip Plain files]| release date=Unknown| author=Ian Micheal| original=M.A.M.E. source code 0.71| systems=Atari Lynx| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ian Micheal Updated: 16-02-04 Description: An emulator for the handheld Atari Lynx. This is based off Ice88/Warmtoes work on M.E.S.S. and M.A.M.E. source code 0.71. It's running at about 36fps, which is a great speed for lynx. The only game tested is rygar, so other game speeds may vary. Speed: 70% Sound: Unknown Links: [http://www.dcemulation.org/phpBB/viewtopic.php?t=36622 Mess build Atari lynx release!] =Downloads= * v1 - [http://www.dcemulation.org/files/emulators/lynxdc.zip Plain files] * v1 - [http://www.dcemulation.org/files/sbi3.0/LynxDC_MESS_CG.sbi SBI file] [[category:emulator]] 5846179f52fb162d0312134e382529dc4788e474 OswanDC 0 906 2065 2023-03-01T21:35:15Z Unknown user 0 Created page with "Developer: [http://www.fmf.nl/~timo/project/oswandc.html Timo Laman] Updated: 08-21-02 A port of Oswan a Bandai WonderSwan (& WonderSwan Color) emulator '''SCREENSHOTS H..." wikitext text/x-wiki Developer: [http://www.fmf.nl/~timo/project/oswandc.html Timo Laman] Updated: 08-21-02 A port of Oswan a Bandai WonderSwan (& WonderSwan Color) emulator '''SCREENSHOTS HOSTED AT DCHOMEBREW''' Speed: 99% Sound: 10% [http://www.dcemulation.org/files/emulators/oswandc-bin-0.15.zip Plain Files] 0.15 Sound enabled '''BROKEN LINKS''' [http://www.dchomebrew.org/zacmcd/Files/oswandc.zip Plain Files] 0.1 [http://www.dchomebrew.org/zacmcd/Files/oswandc-NERO.zip Nero] 0.1 [http://www.dchomebrew.org/zacmcd/Files/oswandc-DJ.zip Discjuggler] 0.1 '''END BROKEN LINKS''' [http://www.dcemulation.org/files/sbi2.1/Oswandc.sbi Selfboot Inducer] 0.1, .015, Fullscreen 680dbad5a4d45a0720860529846369807381d8f6 File:PokeMiniDream.jpg 6 907 2066 2023-03-01T21:36:41Z Unknown user 0 wikitext text/x-wiki PokeMiniDream 0e4ce4accc725bb94d5be76932d191f37ff74989 PokeMini Dream 0 908 2067 2023-03-01T21:36:44Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=PokeMini Dream| image=[[Image:PokeMiniDream.jpg|center|256px|Game Screen]]| homepage=[http://pokeme.shizzle.it/ Homepage]| version=2.0..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=PokeMini Dream| image=[[Image:PokeMiniDream.jpg|center|256px|Game Screen]]| homepage=[http://pokeme.shizzle.it/ Homepage]| version=2.0| downloads=Plain Files:<br>[http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2.zip NTSC 2.0]<br>[http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2PAL.zip PAL 2.0]| release date=9/11/04| author=[[JustBurn]]| original=[http://pokeme.shizzle.it/ PokeMini] by<br/>JustBurn| systems=Pokémon mini| best=Only| refreshrate=50Hz/60Hz| isactive=No }} PokeMini Dream is a Dreamcast port by [[JustBurn]] of his Pokemon mini emulator for Windows. It has no sound/rumble support. Only a handful of public domain roms I tried worked, but the PD roms/demos that I tested can be found below. A variety of demos, PD roms (including what I tested), and the Win32 version emulator can be found download at the host site [http://pokeme.shizzle.it/ Team Pokémé]. Check under the "Files" section. =Controls= File List: *Button A = Select File *Button B = Go Parent Directory *DPAD Left = Move Prev. Page *DPAD Right = Move Next Page *DPAD Up = Cursor Up *DPAD Down = Cursor Down In-Game: *Button A = Button A of Pokemon Mini *Button B = Button B of Pokemon Mini *Button Y = Button C of Pokemon Mini *Button X = Not Used yet (For Shock Detector) *DPAD Left = DPAD Left of Pokemon Mini *DPAD Right = DPAD Right of Pokemon Mini *DPAD Up = DPAD Up of Pokemon Mini *DPAD Down = DPAD Down of Pokemon Mini *Joystick X/Y = Same as DPAD *Start = Power Button of Pokemon Mini *L+R Triggers (Less that 2 secs pressed) = Reset ROM *L+R Triggers (More that 2 secs pressed) = Go to Filelist =Downloads= *Version 2 NTSC - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2.zip Plain Files (Unscrambled)] - 09/11/04 *Version 2 PAL - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2PAL.zip Plain Files (Unscrambled)] - 09/11/04 *Version 1 NTSC - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream1.zip Plain Files (Unscrambled)] - 08/26/04 *Version 1 PAL - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream1PAL.zip Plain Files (Unscrambled)] - 08/26/04 *Public Domain (PD) Roms - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PDroms.zip Zipfile] 6e437a3c1d999e9695447c70dcf2fe80ebbfbab9 2068 2067 2023-03-01T21:37:35Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=PokeMini Dream| image=[[File:PokeMiniDream.jpg|center|256px|Game Screen]]| homepage=[http://pokeme.shizzle.it/ Homepage]| version=2.0| downloads=Plain Files:<br>[http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2.zip NTSC 2.0]<br>[http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2PAL.zip PAL 2.0]| release date=9/11/04| author=[[JustBurn]]| original=[http://pokeme.shizzle.it/ PokeMini] by<br/>JustBurn| systems=Pokémon mini| best=Only| refreshrate=50Hz/60Hz| isactive=No }} PokeMini Dream is a Dreamcast port by [[JustBurn]] of his Pokemon mini emulator for Windows. It has no sound/rumble support. Only a handful of public domain roms I tried worked, but the PD roms/demos that I tested can be found below. A variety of demos, PD roms (including what I tested), and the Win32 version emulator can be found download at the host site [http://pokeme.shizzle.it/ Team Pokémé]. Check under the "Files" section. =Controls= File List: *Button A = Select File *Button B = Go Parent Directory *DPAD Left = Move Prev. Page *DPAD Right = Move Next Page *DPAD Up = Cursor Up *DPAD Down = Cursor Down In-Game: *Button A = Button A of Pokemon Mini *Button B = Button B of Pokemon Mini *Button Y = Button C of Pokemon Mini *Button X = Not Used yet (For Shock Detector) *DPAD Left = DPAD Left of Pokemon Mini *DPAD Right = DPAD Right of Pokemon Mini *DPAD Up = DPAD Up of Pokemon Mini *DPAD Down = DPAD Down of Pokemon Mini *Joystick X/Y = Same as DPAD *Start = Power Button of Pokemon Mini *L+R Triggers (Less that 2 secs pressed) = Reset ROM *L+R Triggers (More that 2 secs pressed) = Go to Filelist =Downloads= *Version 2 NTSC - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2.zip Plain Files (Unscrambled)] - 09/11/04 *Version 2 PAL - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2PAL.zip Plain Files (Unscrambled)] - 09/11/04 *Version 1 NTSC - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream1.zip Plain Files (Unscrambled)] - 08/26/04 *Version 1 PAL - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream1PAL.zip Plain Files (Unscrambled)] - 08/26/04 *Public Domain (PD) Roms - [http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PDroms.zip Zipfile] cfd6c0b6a425d2dc05b8db11c437b18b677c200b Neko Project II 0 909 2069 2023-03-01T22:02:03Z Unknown user 0 Created page with "A full speed PC-9801 emulator for Dreamcast based on [http://www.retropc.net/yui/np2.html Neko Project II]. ''Via [http://en.wikipedia.org/wiki/PC-9801 Wikipedia]:''<br/> "Th..." wikitext text/x-wiki A full speed PC-9801 emulator for Dreamcast based on [http://www.retropc.net/yui/np2.html Neko Project II]. ''Via [http://en.wikipedia.org/wiki/PC-9801 Wikipedia]:''<br/> "The NEC PC-9801 (or the PC-98 for short) is a Japanese microcomputer manufactured by NEC. It first appeared in 1982, and employed an 8086 CPU. It ran at a clock speed of 5 MHz, with two µPD7220 display controllers (one for text, the other for video graphics), and shipped with 128 KB of RAM, expandable to 640 KB. Its 8-color display had a maximum resolution of 640×400 pixels. Its successor, the PC-9801E, which appeared in 1983, employed an 8086-2 CPU, which could selectably run at a speed of either 5 or 8 MHz." ==Needed files== In data directory *BIOS.ROM *FONT.ROM or FONT.BMP or FONT.TMP *SOUND.ROM (optional) ==How to burn== ''W.I.P.'' ==Downloads== *0.82 - [http://prdownloads.sourceforge.net/neko/np2-0.82-dreamcast.zip Plain Files] - 11/08/08 *0.82 - [http://prdownloads.sourceforge.net/neko/np2-0.82-dreamcast-src.tar.bz2 Source] - 11/08/08 ==Links== Neko Project II Dreamcast page *http://neko.sourceforge.net/np2.html Neko Project II official website *http://www.retropc.net/yui/np2.html Sourceforge project page *http://sourceforge.net/projects/neko/ List of PC-9801 games'': Wikipedia'' *http://en.wikipedia.org/wiki/Category:NEC_PC-9801_games 00fbb98fbdf3fce8627123b38c1ea9ab6a195d23 Whack-a-Mole 0 910 2070 2023-03-01T22:02:23Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Whack-a-Mole| image=N/A| homepage=Unknown| version=0.900| downloads=[http://www.dcemulation.org/files/emulators/wam.bin.zip Plain Fil..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Whack-a-Mole| image=N/A| homepage=Unknown| version=0.900| downloads=[http://www.dcemulation.org/files/emulators/wam.bin.zip Plain Files(Scrambled)]| release date=Unknown| author=[[Toastman]]| original=N/A | systems=Chip 8| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Toastman Updated: 16-02-04 Description: A Chip 8 emulator that comes with a bunch of games. =Downloads= * v0.900 - [http://www.dcemulation.org/files/emulators/wam.bin.zip Plain Files(Scrambled)] 510kb * v0.900 - [http://www.dcemulation.com/files/emulators/wam.elf.zip Plain Files(Raw ELF)] 520kb [[Category:Emulator]] 5c0e8684e04944a2afac48b7963c3e406665e678 FreeSCI 0 911 2071 2023-03-01T22:03:11Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=FreeSCI| image=| homepage=[http://freesci.linuxgames.com/?page=main Homepage]| version=0.6.4| downloads=[http://www-plan.cs.co..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=FreeSCI| image=| homepage=[http://freesci.linuxgames.com/?page=main Homepage]| version=0.6.4| downloads=[http://www-plan.cs.colorado.edu/creichen/freesci/freesci-0.6.4-dc.zip Plain Files]<br/>[http://www-plan.cs.colorado.edu/creichen/freesci/freesci-0.6.4.tar.bz2 Source]| release date=05/18/08| author=Walter van Niftrik| original=[http://freesci.linuxgames.com/?page=main FreeSCI]| systems=SCI0 based adventure games| NTSCVGAPAL=Unknown| firstversion=Unknown| best=No, [[ScummVM]]| isactive=No| }} An interpreter for SIERRA adventure games using ''Sierra's Creative Interpreter'' (SCI), ported to Dreamcast by Walter van Niftrik (aka Phantom). ==About FreeSCI== ''Via [http://en.wikipedia.org/wiki/FreeSCI#Related_software Wikipedia]:''<br/> "FreeSCI is an open source engine that can run SCI0 games. FreeSCI works on Linux/Unix, Microsoft Windows, Sega Dreamcast, and GP32." "An open source program called [http://en.wikipedia.org/wiki/SCI_Studio SCI Studio] is available that lets users create games that are based on the SCI0 engine. SCI Studio is designed for Windows. On Linux, using Wine version 20050830, SCI Studio seems to work for editing games, but not for testing or running them. The workaround is to use SCI Studio for development and FreeSCI for game testing." ==Supported Games== ''List from: [http://freesci.linuxgames.com/?page=faq#entry-Whichgamescanthemostrecent'stable'version(0.3.5)run? freesci.linuxgames.com]'' *Leisure Suit Larry 2 *Leisure Suit Larry 3 *Police Quest 2 *King's Quest 4 *Quest for Glory 1/Hero's Quest *Space Quest 3 *Hoyle's Book of Games *The Colonel's Bequest *Conquest of Camelot *Hoyle's Book of Games 2 *Codename: Iceman ==SCI Studio== ''Via [http://www.bripro.com/scistudio/ SCI Studio website]:''<br /> "Have you ever wanted to make an adventure game like Sierra's King's Quest, Space Quest, Police Quest, Leisure Suit Larry or Quest for Glory? Well, now you can! With SCI Studio, you can create games using the exact same engine Sierra used! If you aren't familiar with SCI Studio, check out the [http://www.bripro.com/scistudio/faq.php FAQ page]." ''Via [http://en.wikipedia.org/wiki/SCI_Studio Wikipedia]:''<br /> "SCI Studio, software intended for creating games that execute using the classic Sierra's Creative Interpreter, was originally the progeny of Brian Provinciano. The software was worked on by Provinciano for many years, but on 25 March 2006 he announced on his website the cessation of work on his part, and released the complete archive of the SCI Studio source-code into the public domain (which contained much progress in the development of the program, which was never before seen in an official release). SCI Studio can also be considered an IDE for SCI Games for Microsoft Windows Operating Systems. All games created with SCI Studio run with Sierra's SCI0 Interpreter (SCIV.EXE) and the open source interpreter for Windows/MacOS/Linux/Sega's DreamCast and more, FreeSCI." ==Older Versions== *0.3.5 - [http://www-plan.cs.colorado.edu/creichen/freesci/freesci-0.3.5-dc.zip Plain Files] ==Links== Wikipedia SCI article: *http://en.wikipedia.org/wiki/FreeSCI List of SCI Games: *http://en.wikipedia.org/wiki/SCI_Games SCI Studio website: *http://www.bripro.com/scistudio/ FreeSCI merge with ''ScummVM?'': *http://www.scummvm.org/faq/#2_4 69948ac0306a94f4505968a0e63db639b98154e2 File:Vta.png 6 912 2072 2023-03-01T22:04:38Z Unknown user 0 wikitext text/x-wiki Vta 1c16e23fd2ddef2b09ada4d34c8e4121fbafaad6 Visual Troy Advance 0 913 2073 2023-03-01T22:04:45Z Unknown user 0 Created page with "== Visual Troy Advance == {{Infobox_Emulator_Information| name=Visual Troy Advance| image=[[Image:vta.png|center|250px]]| homepage=[http://gpf.dcemu.co.uk/visualtroyadvanc..." wikitext text/x-wiki == Visual Troy Advance == {{Infobox_Emulator_Information| name=Visual Troy Advance| image=[[Image:vta.png|center|250px]]| homepage=[http://gpf.dcemu.co.uk/visualtroyadvance.shtml Homepage]| version=1.4| downloads=[http://dcemulation.com/1-newsdump/emulators/VTA1.4.rar Binary (Plain Files)]<br/>[http://dcemulation.com/1-newsdump/emulators/VisualBoyAdvance1.80DCSrc.rar Source Code]<br/>| release date=06/03/2005| author=GPF (Troy Davis)<br/>| original=VBA-Team<br/>(Visual Boy Advance)| systems=GBA/GB/GBC| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Visual Troy Advance is a port of Visual Boy Advance 1.80 by GPF. Visual Troy Advance runs very slow. == Controls == *X = B *A = A *L Trigger = L *R Trigger = R *Start = Start *Y = Select 56202c34ae7ab79c5657a95045892ab2592a2c9a 2074 2073 2023-03-01T22:04:51Z Unknown user 0 wikitext text/x-wiki == Visual Troy Advance == {{Infobox_Emulator_Information| name=Visual Troy Advance| image=[[File:vta.png|center|250px]]| homepage=[http://gpf.dcemu.co.uk/visualtroyadvance.shtml Homepage]| version=1.4| downloads=[http://dcemulation.com/1-newsdump/emulators/VTA1.4.rar Binary (Plain Files)]<br/>[http://dcemulation.com/1-newsdump/emulators/VisualBoyAdvance1.80DCSrc.rar Source Code]<br/>| release date=06/03/2005| author=GPF (Troy Davis)<br/>| original=VBA-Team<br/>(Visual Boy Advance)| systems=GBA/GB/GBC| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Visual Troy Advance is a port of Visual Boy Advance 1.80 by GPF. Visual Troy Advance runs very slow. == Controls == *X = B *A = A *L Trigger = L *R Trigger = R *Start = Start *Y = Select ecbd73338dac733bcc6526be4595670e33e889d2 DC64 0 914 2075 2023-03-01T22:05:44Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DC64| image=No Screenshot Available| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=Beta 4| downloads=See..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC64| image=No Screenshot Available| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=Beta 4| downloads=See List<br/>| release date=11/01/01| author=BigBoy| original=N/A| systems=Commodore 64| best=Unknown| isactive=No }} Developer: BigBoy<br/> Version: Beta 4<br/> Last Updated: 11-01-01<br/> Description: Finally, a commodore 64 emulator for dreamcast, this version is just a test demo, showing you of what it can do so far. Latest Status: <br/> Still Sanxion, running nice and smooth now. Only a few games do just now, speed changes depending on the game. Uridium and Sanxion both seem to be at full "smooth" speed. However there is still no input, and this WILL slow it down again...*sigh* I will try and add basic input soon. There is no Sprite-2-???? collision. This would slow things down a LOT! <br/> =Downloads= * Beta 4 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dc64beta4.zip Plain Files] Selboot:No 345kb * Beta 4 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dc64beta4DJ.zip Disk Juggler] Selfboot:Yes 370kb =Old Version= * Beta 3 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dc64beta3.zip Plain Files] Selfboot:No 357kb * Beta 3 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/DC64DJ.zip Disk Juggler] Selfboot:Yes 212kb * First release - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/DC64sbb.zip Plain Files] Selfboot:No 208kb SelfBoot Buddy INI included. [[Category:Emulator]] 522932b34dfea3de174bb9a7152faa9fe8295dd5 Apple II Soul Captor 0 915 2076 2023-03-01T22:06:04Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Apple II Soul Captor| image=No Image Available| homepage=Unknown| version=August, 2002| downloads=[http://www.dcemulation.org/..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Apple II Soul Captor| image=No Image Available| homepage=Unknown| version=August, 2002| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/a2sc-bin-1.zip Plain Files] | release date=Unknown| author=[http://consolevision.com/members/dcgrendel/ DCGrendel]| original=N/A| systems=Apple II / II+| best=Unknown| isactive=No }} Developer: [http://consolevision.com/members/dcgrendel/ DCGrendel] <br> Updated: August, 2002 <br> <br> Emulation of the Apple II and II+ computers, with support for save states, disk images (read only), multilingual menu support (English menus distributed, third parties are welcome to translate the menu files into their home language.) <BR><BR> Speed: 100% Sound: 50% ==Downloads== [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/a2sc-bin-1.zip Plain Files] 6ab3ad7bd54094804f1ea28f884b561c830f8c67 DreamFrodo 0 916 2077 2023-03-01T22:06:30Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DreamFrodo| image=N/A| homepage=[http://frodo.boob.co.uk/ Homepage]| version=V0.94| downloads=See List<br/>| release date=Unk..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamFrodo| image=N/A| homepage=[http://frodo.boob.co.uk/ Homepage]| version=V0.94| downloads=See List<br/>| release date=Unknown| author=Tolga Abaci| original=(Frodo)| systems=Commodore 64| best=Unknown| isactive=Unknown }} Developer: Tolga Abaci Updated: 26-07-03 Description: A port of the Commodore 64 emulator Frodo. =Downloads= * v0.94 - [http://www.dcemulation.org/files/emulators/DreamFrodo.0.94.bin.st.zip Plain Files] Binary "standard" 200kb * v0.94 - [http://www.dcemulation.org/files/emulators/DreamFrodo.0.94.bin.pc.zip DiscJuggler] Binary "precise cycle" 200kb * v0.94 - [http://www.dcemulation.org/files/emulators/DreamFrodo.0.94.src.zip Source] Source 547kb [[Category:Emulator]] d7e2422f267e1165367a8b3bd556e6a6ec18647c File:Umsx.png 6 917 2078 2023-03-01T22:07:48Z Unknown user 0 wikitext text/x-wiki Umsx 7c5e226193fab200f48860a4b87dae94c7568e97 Panera 64 0 918 2079 2023-03-01T22:08:16Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Panera 64| image=No Screenshot Available| homepage=[http://www.dreamcast.es/news.php?readmore=124 Homepage]| version=Alpha 01| downlo..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Panera 64| image=No Screenshot Available| homepage=[http://www.dreamcast.es/news.php?readmore=124 Homepage]| version=Alpha 01| downloads=[http://www.maturion.de/dreamcast/dateien/emulatoren/panera6401a.rar Plain Files]| release date=07/31/2008| author=[[ron]]| original=[http://frodo.cebix.net/ Frodo]/[[DreamFrodo]]<br />(Christian Bauer)| systems=Commodore 64| best=Probarbly.| refreshrate=50Hz / 60Hz| isactive=Unknown }} [[ron]] took [[DreamFrodo]] 0.94 by [[Tolga Abaci]], which was built with [[KallistiOS]] 0.91, tweaked some code and made it use a modern toolchain. The result is Panera 64 - in its first alpha version it runs fullspeed without frameskip, supporting two pads and the Dreamcast keyboard. There's even a virtual keyboard you can access by pressing X on your controller and also a main menu by pressing Start. A German and a French version are planned for the future. You can discuss about Panera 64 [http://dcemulation.org/phpBB/viewtopic.php?f=72&t=97628 here]. Below is video of Panera 64: *http://www.youtube.com/watch?v=4tl0xhaNAwk aa6fa4a8a6942385486e0ee45e703cedb921250a VMoo 0 919 2080 2023-03-01T22:09:30Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=VMoo| image=N/A| homepage=[http://bullandfish.net Homepage]| version=Alpha 1| downloads=See List<br/>| release date=Unknown|..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=VMoo| image=N/A| homepage=[http://bullandfish.net Homepage]| version=Alpha 1| downloads=See List<br/>| release date=Unknown| author=Dirty Sanchez| original=Marcus Comstedt<br/>(VMU Emulator)| systems=DreamCast VMU| best=No| isactive=No }} Developer: Dirty Sanchez<br/> Updated: 08-02-04<br/> Description: <br/> VMoo Mad Cow/Chao Edition Alpha 1 is a port of Marcus Comstedt's VMU emulator to run on the Dreamcast. The speed is about 90-95% correct. =Downloads= * Alpha 1 - [http://www.dcemulation.org/files/emulators/vmoo.elf.gz Plain Files] Elf [[category:Emulator]] 0238e1b52b1c07e4bada2f010e365f33ecc12aba 2081 2080 2023-03-01T22:09:35Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=VMoo| image=N/A| homepage=[http://bullandfish.net Homepage]| version=Alpha 1| downloads=See List<br/>| release date=Unknown| author=Dirty Sanchez| original=Marcus Comstedt<br/>(VMU Emulator)| systems=DreamCast VMU| best=No| isactive=No }} Developer: Dirty Sanchez<br/> Updated: 08-02-04<br/> Description: <br/> VMoo Mad Cow/Chao Edition Alpha 1 is a port of Marcus Comstedt's VMU emulator to run on the Dreamcast. The speed is about 90-95% correct. =Downloads= * Alpha 1 - [http://www.dcemulation.org/files/emulators/vmoo.elf.gz Plain Files] Elf [[category:Emulator]] 0514dbad4002dfd20df7dc654cc2bae4db02dd62 SoftVMS 0 920 2082 2023-03-01T22:10:02Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SoftVMS| homepage=[http://mc.pp.se/dc Homepage]| version=1.0| downloads=[http://www.dcemulation.org/files/pcemu/softvms.tar.gz Downloa..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SoftVMS| homepage=[http://mc.pp.se/dc Homepage]| version=1.0| downloads=[http://www.dcemulation.org/files/pcemu/softvms.tar.gz Download]| release date=10/30/00| author=Marcus Comstedt| original=[http://mc.pp.se/dc SoftVMS]<br/>by Marcus Comstedt| systems=Dreamcast VMU| firstversion=Unknown| best=Maybe?| refreshrate=N/A - For PC| isactive=No }} SoftVMS is a Dreamcast VMU emulator for the PC. e139bcd5f15f2ee66bd7089966404037fba3f303 UMSX 0 921 2083 2023-03-01T22:11:42Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=uMSX| image=[[Image:umsx.png|center|250px]]| homepage=[http://www.developia.info/viewtopic.php?f=9&t=19 Homepage]| version=0.2| downl..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=uMSX| image=[[Image:umsx.png|center|250px]]| homepage=[http://www.developia.info/viewtopic.php?f=9&t=19 Homepage]| version=0.2| downloads=[http://developia.googlecode.com/files/uMSX-DCbin-0.2.tar.bz2 Plain Files]| release date=07/01/2008| author=[[Uguru]]| original=[http://fms.komkon.org/fMSX/ fMSX]<br />(Marat Fayzulin)| systems=MSX| best=Probarbly.| refreshrate=50Hz / 60Hz| isactive=Unknown }} uMSX is a Mircosoft MSX emulator. It is based on Marat Fayzulin's fMSX emulator and was ported by [[Uguru]]. It supports sound and saving to a VMU and has a nice user interface. a621ce984828800df822c8318b6e190004ac3335 NeoPocott DC 0 922 2084 2023-03-01T22:12:22Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=NeoPocott DC| image=No Screenshot Available| homepage=[http://www.ganksoft.com Homepage]| version=V1.0| downloads=See List<br/..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=NeoPocott DC| image=No Screenshot Available| homepage=[http://www.ganksoft.com Homepage]| version=V1.0| downloads=See List<br/>| release date=04/25/04| author=Ganksoft| original=Julien Frelat<br/>(NeoPocott DC)| systems=NeoGeo Pocket| best=Unknown| isactive=Unknown }} Updated: 12-26-00 <br/> Description: A Neo Geo Pocket Color emulator for the Sega Dreamcast. It is a port of Julien Frelat's emulator of the same name. Speed: 75% <br/> Sound: None =Downloads= * 1.0 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/npdc10if.zip Plain Files] 431kb * 1.0 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/npdc10dj.zip Discjuggler] 1.27mb * 1.0 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/npdc10ne.zip Nero] 982kb * 1.0 - [http://www.dcemulation.org/files/sbi2.1/Neopocott.sbi Selfboot Inducer] (Sbi v2.1) 401kb =Tutorials= * [http://www.dcemulation.org/files/readme/neopocottdc1.0.txt NeoPocott DC v1.0 README file] * [http://www.dcemulation.org/selfboot-neopocott.htm Selfbooting NeoPocott with Selfboot] - A tutorial using burner's Selfboot tool. * [http://www.dcemulation.org/roms-neopocott.htm NeoPocott Roms disc] - Burning a NeoPocott roms disc with Nero. [[Category:Emulator]] b62c891182b3126d19d41d923bb878cbbf74e1f4 RACE!DC 0 923 2085 2023-03-01T22:12:44Z Unknown user 0 Created page with "RACE!DC, which stands for Rather A Cardfighter Emulator!, is a Neo Geo Pocket Color emulator for the Dreamcast. It was ported by [[GPF]]." wikitext text/x-wiki RACE!DC, which stands for Rather A Cardfighter Emulator!, is a Neo Geo Pocket Color emulator for the Dreamcast. It was ported by [[GPF]]. 0f6840142475fe7f4f083e0e73075c4e7b0e1199 DirectVMS 0 924 2086 2023-03-01T22:14:37Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DirectVMS| homepage=No longer exists,<br />was http://www.fallenrealm.com/directvms/index.html| version=1.8| downloads=[http://www.dce..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DirectVMS| homepage=No longer exists,<br />was http://www.fallenrealm.com/directvms/index.html| version=1.8| downloads=[http://www.dcemulation.org/files/pcemu/DirectVMUexec.zip Executable]<br/>[http://www.dcemulation.org/files/pcemu/DirectVMUsource.zip Source Code]| release date=9/24/00| author=Fallen Realm| original=DirectVMS<br/>by Fallen Realm| systems=Dreamcast VMU| firstversion=Unknown| best=Maybe?| refreshrate=N/A - For PC| isactive=No }} DirectVMS is a Dreamcast VMU emulator for the PC. b9ffc6e389dbf84bd3f361af6fcbf4d0300c6da8 VMU emulators 0 118 2087 377 2023-03-01T22:17:09Z Unknown user 0 wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official Page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= The original VMU emulator, written by the man who helped to reverse engineer the platform and kickstart the homebrew scene. * Official Page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android =Visual Memory Emulator= * Google Play : [https://play.google.com/store/apps/details?id=com.nuritsubushi.vmemu] * Developer : Kum * Compatibility : Unknown * Platform(s) : Android =DirectVMS= *Developer : [http://www.fallenrealm.com/directvms/index.html Fallen Realm] *Platforms: Windows * Latest release: 1.8, 09/24/2000 * Download [http://www.dcemulation.org/files/pcemu/DirectVMUexec.zip Binary], [http://www.dcemulation.org/files/pcemu/DirectVMUsource.zip Source Code] 03024f04fe60cd1f5d947e1a60c69ec38f1c4fd2 Old tools 0 195 2088 657 2023-03-01T22:29:18Z Unknown user 0 wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] 62cd9be38da0e40bb5ce759c3d6eb475dc3a75a2 2089 2088 2023-03-01T22:29:33Z Unknown user 0 /* MR Image insertion programs */ wikitext text/x-wiki This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] 1bbbed5c1efd8a9ea9cc5428ee179c1b0ff812d0 Chui 0 925 2090 2023-03-01T22:32:04Z Unknown user 0 Created page with "Chui is a Spanish Dreamcast developer. He did a lot of projects and he is very well known for maintaining the Dreamcast port of [[SDL]] and OpenGL. He is working on a remake o..." wikitext text/x-wiki Chui is a Spanish Dreamcast developer. He did a lot of projects and he is very well known for maintaining the Dreamcast port of [[SDL]] and OpenGL. He is working on a remake of Return to Castle Wolfenstein for Dreamcast and he is also porting the well known game development library Allegro to the Dreamcast. *[[NEO4ALL]] - Alternative open source NEOGEO/CD emulator. *[[AES4ALL]] - NEO4ALL fork for emulating home and arcade NEOGEO systems. *[[DCASTAWAY]] - The first Atari ST emulator. *[[UAE4ALL]] - Open source Amiga500 emulator. *[[SNES4ALL]] - Alternative Snes9x port (Super Nintendo emulator). *[[ZX4ALL]] - Open source ZX-Spectrum emulator. *[[MAME4ALL]] - MAME GP2X adaptation for Dreamcast. *[[PSX4ALL]] - Open source Playstation emulator. *[[NOIZ2SA]] - Abstract shoot'em up. *[[FENIX]] - The way to game development. *[[SDL]]+OpenGL : Dreamcast SDL and OpenGL. ==Weblinks== *[[http://chui.dcemu.co.uk/ Chui's Homepage]] *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=28344 Chui's profile on DCEmulation] b22b4a8926c3e88618f26736c9722d02a790cef4 File:Boobboy.jpg 6 926 2091 2023-03-01T22:34:54Z Unknown user 0 wikitext text/x-wiki Boobboy a65607730bc350dc4356d9d828c76672515c1f2a Boob!boy 0 927 2092 2023-03-01T22:35:12Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Boob!boy| image=[[Image:boobboy.jpg|center|thumb|250px| Boob!boy]]| homepage=[http://www.boob.co.uk/emulators/gameboy.html Homep..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Boob!boy| image=[[Image:boobboy.jpg|center|thumb|250px| Boob!boy]]| homepage=[http://www.boob.co.uk/emulators/gameboy.html Homepage]| version=1.5| downloads=[http://www.dcemulation.org/files/emulators/Boob!boy.zip Plain Files]| release date=12/22/2000| author=[[CyRUS64]]| original=Boob!boy| systems=Nintendo GameBoy<br />GameBoy Color| best=No| refreshrate=60Hz| isactive=No }} ==History== Boob!boy is the first Gameboy emulator for the Dreamcast by [[CyRUS64]]. Its name is inspired by the Dreamcast website B00B! Dreamcast Research, since the author, [[CyRUS64]], was the founder of B00B!. Unlike most other emulators, Boob!boy was written from scratch and is not a normal port. There also exists a PC version of Boob!boy which supports sound. ''Screenshots:<br/>[http://www.dcemulation.org/images/screens/boob_boy01.jpg Image 1], [http://www.dcemulation.org/images/screens/boob_boy02.jpg Image 2], [http://www.dcemulation.org/images/screens/boob_boy03.jpg Image 3],<br/>[http://www.dcemulation.org/images/screens/boob_boy04.jpg Image 4], [http://www.dcemulation.org/images/screens/boob_boy05.jpg Image 5], [http://www.dcemulation.org/images/screens/boob_boy06.jpg Image 6]. ===Feaures=== * Frameskip implemented - Boob!boy should now be faster with only a small amount of frameskipping noticeable. For example, Super Mario Land without doubt now runs at FULL SPEED. * Super Gameboy Support added * Fixed a memory problem that meant memory wasn't being freed up after the game was exited and hence when you had played 4/5 games the dc would run out of memory and crash. You should now be able to play as many different games as you want without having to reset the dc! * Swapped around A and B keys to make it more like a real gameboy! * New menus - a license screen is now displayed explaining that Boob!boy is not licensed or endorsed by Sega. Also a menu screen has been implemented which currently only features a play game option... (pretty pointless at the moment then!) * Made game-select screen more user-friendly by speeding up page-select and game-select movements * Fixed bug causing a delay before loading the game to be played * Implemented load from file functions saving much-needed memory... This also has resulted in a speed-up in the emulation since Video Ram can now be used for more important tasks! * Found and "zapped" other little bugs in the code, which although didn't cause any problems in current versions would have done so in the future. ===Bugs=== * Since sound caused Boob!boy to crash on the Dreamcast, it has been disabled in the Dreamcast version. ==Downloads== * 1.5 - [http://www.dcemulation.org/files/emulators/Boob!boy.zip Plain Files] - 12/22/2000 * 1.5 - [http://www.dcemulation.org/files/sbi2.1/Boobboy.sbi SBI] - 12/22/2000 * 1.5 beta - [http://web.archive.org/web/20031222225609/http://www.dcemulation.com/dl/dl.php3?url=files/emulators/Boob!boy.zip Plain Files] - ''Unknown release date * 1.5 - [http://www.dcemulation.org/?title=Boob!boy.nfo NFO Info file] 218e62f09d0a12b31ec8185e1967b3bc579d2f04 Gnuboy/DC 0 928 2093 2023-03-01T22:36:06Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=gnuboy/DC| image=[[Image:Gnuboydc.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/?gnuboy%2FDC Current]<br/>/[http:/..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=gnuboy/DC| image=[[Image:Gnuboydc.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/?gnuboy%2FDC Current]<br/>/[http://pqrs.org/dreamcast/software/dcgnuboy/ Old]| version=1.0.4| downloads=[http://dchelp.dcemulation.org/?download=gnuboydc_104.zip Plain Files]<br/>[http://dchelp.dcemulation.org/?download=gnuboydc_104_src.zip Source]| release date=04/06/2008| author=emptythought ''(1.0.4 ↑)''<br/>[[Takayama Fumihiko]] ''(1.0.3 ↓)''| original=[http://brightrain.aerifal.cx/~laguna/ Gnuboy]| systems=Nintendo Gameboy/<br/>Gameboy Color| refreshrate=60Hz| firstversion=''Unknown| best=Yes| isactive=Yes| }} ==History== A great port of the Gameboy Color emulator gnuboy by [[Takayama Fumihiko]], which he left at version '1.0.3-0.6'. It later received some minor updates by Fackue, with help from [[Quzar]]. It now has support for zipped roms (.zip), and slightly higher game compatibility. ===Features=== * GB/GBC emulate with sound. * smooth sound with GBC. * save support (with long filename support) * state save/load * frameskip. * screen adjustment. * added support for Zipped roms * save icon for VMU saves ===Bugs=== * ROM path display ==Downloads== * 1.0.4 - [http://dchelp.dcemulation.org/?download=gnuboydc_104.zip Plain Files] - 04/06/2008 * 1.0.4 - [http://dchelp.dcemulation.org/?download=gnuboydc_104_src.zip Source] - 04/06/2008 * 1.0.3 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/gnuboy-1.0.3-0.6.zip Plain Files] - 08/04/2002 * 1.0.3 - [http://www.dcemulation.org/files/sbi2.1/Gnuboy.sbi SBI] - 08/04/2002 * 1.0.3 - [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dcgnuboyNero.zip Nero] - 08/04/2002 * 1.0.3 - [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dcgnuboyDJ.zip DiscJuggler] - 08/04/2002 * 1.0.3 - [ftp://ftp.pqrs.org/dc/gnuboy/source/dcgnuboy-1.0.3-0.6.tar.gz Source] - 08/04/2002 ==Links== * [http://www.dcevolution.net/index.php?id=gameboy_gameboy_color DCEvolution]: Dream Emulation Project * [http://sourceforge.net/projects/gnuboydc/ Sourceforge]: Hosted Page 3ceef4dad86bba96f55c1e2958c7f0821f985305 File:Gnuboydc.jpg 6 929 2094 2023-03-01T22:36:22Z Unknown user 0 wikitext text/x-wiki Gnuboydc a920f45201ee15ee009574f0b870f7daa37c7f79 Single-game MAME releases 0 930 2095 2023-03-01T22:38:30Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Single-game MAME| image=| homepage=''N/A| version=''N/A| downloads=[[#Downloads|Below]]| release date=''Various| author=''Various|..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Single-game MAME| image=| homepage=''N/A| version=''N/A| downloads=[[#Downloads|Below]]| release date=''Various| author=''Various| original=[http://mamedev.org/ MAME]| systems=Various Arcade| best=Probably not,<br/>check [[MAME4ALL]]| refreshrate=50Hz/60Hz| isactive=No| }} ==History== These single game MAME release were developed by James Surine, ice88, IMR, and Metafox. [[James Surine]] ported MAME v0.37b to the DC, and [[ice88]] ported MAME v0.72. [http://imrtechnology.ngemu.com/ IMR], and [[MetaFox]], improved upon their source to release several single game emulators (and a few multiple game emulators). The following games, or collection of games, were released in '.sbi' form. You can add as many as you wish, or can fit, onto a single disc using [http://dchelp.net/tag/selfboot-inducer/ Selfboot Inducer]. ==Downloads== * 1943 ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-1943.sbi SBI] * Araknoid ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-arkanoid.sbi SBI] * Bagman ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-bagman2.sbi SBI] * Bubble Bobble ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-BubbleBobble.sbi SBI] * Cadillacs & Dinosaurs ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-CadillacsDinos.sbi SBI] * CPS1 Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SBI-cps1dc.sbi SBI], [http://www.dcemulation.org/files/emulators/cps1dc.zip Plain] - ''pack that runs CPS1 games'' * Double Dragon ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_DDRAGON.sbi SBI] * Frogger ** by JWT - [http://www.dcemulation.org/files/sbi3.0/JWT_FroggerSGA_CG.sbi SBI] * Galaga ** by IMR - [http://www.dcemulation.org/files/sbi3.0/Galaga_bO.sbi SBI] * Gradius III ** by ? - [http://www.dcemulation.org/files/sbi3.0/SGA-GradiusIII.sbi SBI] * Green Beret ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-GreenBeret.sbi SBI] * Gunsmoke ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Gunsmoke.sbi SBI] * Haunted Castle ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-HauntedCastle_CG.sbi SBI] * Ladybug ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-ladybug.sbi SBI] * Mustache boy ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-mustache.sbi SBI] * Neck & Neck ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-neckneck.sbi SBI] * Pacman Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/IMR-Pacmanpack.sbi SBI], [http://www.dcemulation.org/files/emulators/pacmanpack.zip Plain] - ''(Pac-Man, Jump Shot, Lizard Wizard, Magic Brush, Make Trax (set 1), Mr. TNT, Ms. Pac Man Attacks, Ms. Pac-Man, Puckman) * Paperboy ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-paperboy.sbi SBI] * Parodius ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Parodius.sbi SBI] * Pengo ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-pengo2.sbi SBI] * Perfect Billiard ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-PerfectBilliard_CG.sbi SBI] * Popeye ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-popeye2.sbi SBI] * Puyo Puyo ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-PuyoPuyo.sbi SBI] * Rastan ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_Rastan.sbi SBI] * Robocop ** by IMR - [http://www.dcemulation.org/files/sbi3.0/RobocopSmooth_CG.sbi SBI] * Rygar ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Rygar.sbi SBI] * Scramble ** by IMR - [http://www.dcemulation.org/files/sbi3.0/sga-scramble.sbi SBI] * Shinobi ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Shinobi.sbi SBI] * Simpsons ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_SIMPSONS.sbi SBI] * SimVen ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SimVenv2_CG.sbi SBI] - ''(Simpsons, Vendetta) ** [http://www.dcemulation.org/files/sbi3.0/SBI-simpsonsvendetta.sbi SBI], [http://www.dcemulation.org/files/emulators/simpsonsvendetta.zip Plain] * Sky Skipper ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-skyskipr.sbi SBI] * Street Fighter II ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Sf2dc.sbi SBI] * Super Sprint ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-ssprint.sbi SBI] * Taito Hits ** by IMR - [http://www.dcemulation.org/files/sbi3.0/TaitoHits_CG.sbi SBI], [http://www.dcemulation.org/files/emulators/taitopack.zip Plain], [http://www.dcemulation.org/phpBB/viewtopic.php?t=38971 Info] - ''(New Zealand story, Arkanoid 2, Extermination, Insector X, kageki, Chuka Taisen, Dr. Toppels Adventure, Plump pop) * Tapper ** by MetaFox - [http://www.dcemulation.org/files/sbi3.0/meta-tapper.sbi SBI] * T.M.N.T. ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Tmnt.sbi SBI] * Vendetta ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_VENDETTA.sbi SBI] * Willow ** by IMR - [http://www.dcemulation.org/files/sbi3.0/sga-willowwip.sbi SBI] * Wonderboy ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Wonderboy.sbi SBI] * X-Men ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_XMEN.sbi SBI] * Xevious ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Xevious.sbi SBI] * Xybots ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Xybots.sbi SBI] * Yie Ar Kung Fu ** by JWT - [http://www.dcemulation.org/files/sbi3.0/JWT_YieArSGA_CG.sbi SBI] ==Links== * DEAD LINK <s>[http://imrtechnology.ngemu.com/sga.htm More SGA Releases]</s> ''via IMR 8c79d47cd24185cb3435864d36799da20a5953b2 File:Dreampac2.jpg 6 931 2096 2023-03-01T22:39:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dreampac2}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ddeed6fc94f1f15c0fa8b2cb2a55608a410d13f3 File:Dreampac1.jpg 6 932 2097 2023-03-01T22:39:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dreampac1}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 5605b73b2175b8f04269e5aadea7c33f29fc40b9 File:Dreampac3.jpg 6 933 2098 2023-03-01T22:39:29Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dreampac3}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ff5e3e7f2ec67f79e13ecef9515e72ccbdc0a337 File:Dreampac4.jpg 6 934 2099 2023-03-01T22:39:29Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dreampac4}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 90a0cac0b8e1d9586998984b4cacdb3fc2d8004c DreamPac 0 935 2100 2023-03-01T22:39:45Z Unknown user 0 Created page with "DreamPac Developer: [http://www.ganksoft.com/ Ganksoft] Version: 1.0 Last Updated: 04-10-01 Description: DreamPac is a Pacman hardware emulator for the Sega Dreamcast. It was..." wikitext text/x-wiki DreamPac Developer: [http://www.ganksoft.com/ Ganksoft] Version: 1.0 Last Updated: 04-10-01 Description: DreamPac is a Pacman hardware emulator for the Sega Dreamcast. It was written from scratch specifically for the Dreamcast platform. At the moment it plays the following games: -Pacman -Ms. Pacman -Crush Roller All games run at full speed and have full sound. More games may be added to this emulator at a later date (either Pacman clones or completely different games). [http://www.dcemulation.org/dl/dl.php3?url=files/software/dp10dj.zip DJ image] [http://www.dcemulation.org/dl/dl.php3?url=files/software/dp10ned.zip Nero DAO image] [http://www.dcemulation.org/dl/dl.php3?url=files/software/dp10net.zip Nero TAO image] [http://www.dcemulation.org/dl/dl.php3?url=files/software/dp10bif.zip Plain files] [[Image:Dreampac1.jpg]] [[Image:Dreampac2.jpg]] [[Image:Dreampac4.jpg]] [[Image:Dreampac3.jpg]] c80ca2c3e2f1a2acd4720cef00460b7506953ce4 File:Dcphoenix01.jpg 6 936 2101 2023-03-01T22:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dcphoenix01}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 739395fe4dc9d824c09c2dc53100493b0eab8cd4 File:Dcphoenix02.jpg 6 937 2102 2023-03-01T22:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dcphoenix02}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 68c92c0619012289e0483098da3ac6bc6636c8c1 File:Dcphoenix03.jpg 6 938 2103 2023-03-01T22:40:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Dcphoenix03}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a44054e90f6af0d5e359f40004484096627023d0 DCPhoenix 0 939 2104 2023-03-01T22:40:52Z Unknown user 0 Created page with "Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. A..." wikitext text/x-wiki Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. Also plays Pleiads. Status: * VMU LCD Logo * Two Player Mode * Sound Support * Initial Pleiads emulation * Better video support. * Controller Support * Source Code Screen Shots: [[Image:Dcphoenix03.jpg]] [[Image:Dcphoenix02.jpg]] [[Image:Dcphoenix01.jpg]] [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dc-phoenix05DJ.zip Disk Jugger] Version 0.5 [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dc-phoenix05.zip Plain Files] Version 0.5 [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dc-phoenix04.zip Plain Files] Version 0.4 30f1c779e65e74ee07d543e902a1917d9fdc9499 DCSI 0 940 2105 2023-03-01T22:41:44Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DCSI| image=N/A| homepage=[http://www.finck.net/dcsi/ Homepage]| version=???| downloads=[http://www.dcemulation.org/files/software/dc..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCSI| image=N/A| homepage=[http://www.finck.net/dcsi/ Homepage]| version=???| downloads=[http://www.dcemulation.org/files/software/dcsi_bin.zip Plain files]| release date=Unknown| author=D. Finck| original=N/A | systems=MAME| best=N/A| refreshrate=''Unknown| isactive=''Unknown| }} Developer: [http://www.finck.net/dcsi/ D. Finck] Version: 0.3? (0.4 is the final, which do we have here?) Last Updated: May 28, 2001 Description: A Space Invaders Emulator for the Dreamcast. =Downloads= * Version Unknown - [http://www.dcemulation.org/files/software/dcsi_cdi.zip Disc Juggler image] * Version Unknown - [http://www.dcemulation.org/files/software/dcsi_bin.zip Plain files] [[category:emulator]] aad022d2709a8443885bdc9cc635db560d9bfccb SIemu 0 941 2106 2023-03-01T22:41:57Z Unknown user 0 Created page with "Developer: Ian Micheal Updated: 2003 An emulator that runs the classic 1970's arcade game, Space Invaders. Speed: 100% Sound: ??? [http://www.dcemulation.org/files/e..." wikitext text/x-wiki Developer: Ian Micheal Updated: 2003 An emulator that runs the classic 1970's arcade game, Space Invaders. Speed: 100% Sound: ??? [http://www.dcemulation.org/files/emulators/siemu.zip Plain Files] [http://www.dcemulation.org/files/sbi3.0/SBI-SIemu.sbi Selfboot Inducer] 6b7af27f3288e6367ba863afc90a39586bf1cf67 File:HOTA 1.jpg 6 942 2107 2023-03-01T22:43:20Z Unknown user 0 wikitext text/x-wiki HOTA 1 75f18fdb3538c38dfe6ecf200252abcde2acc03d Heart of the Alien 0 943 2108 2023-03-01T22:43:25Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heart of the Alien |- border="0" cellpadding="2" cellsp..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heart of the Alien |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:HOTA_1.jpg|280px|thumb|Cut scene]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/hota.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|02/''??''/2006}}} |- style="background:#ffffff" |Author || {{{author|[[LTK]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://hota.sourceforge.net/ Heart of the Alien Redux]}}} |- style="background:#ffffff" |Type of game || {{{type|Classic Adventure}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== ''Via ReadMe<br/> '''''What is HOTA?<br/> '' 'Heart of The Alien is the sequel for the undoubtedly the best adventure of all times, Another World. Developed back in 1994 by Interplay exclusively for the Sega CD console. This is an open-source project which aims to bring this highly-addictive game to all modern consoles and computer platforms. ''Please note, that you are required to own a copy of the game beforehand, as this release loads all game elements from the cd.' ===This Release=== It's a port to Dreamcast. ===Controls=== * Pad: Up, Down, Left, Right, * A → button jump * B → button run * Y → button object * START + X → Skips video scenes / Exits from game * START + L → Fast savestate * START + R → Fast loadstate, only press it after a saved state ==Usage== This release ONLY work with an iso (like the pc version) without music track. The iso file has to be rename to hota.iso and put in a folder called hota Here is the scheme: CD-\ hota\ hota.iso ===Lacks=== * NO mp3 audio support. * Some others. ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/hota.zip Plain Files] - 02/''??''/2006 bb5df87cdf5a1a6e789e9a4f7432232eda3eca0f ZX-Ishspectrum 0 944 2109 2023-03-01T22:47:22Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=ZX-Ishspectrum| image=N/A| homepage=Unknown| version=1.0| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/zx-ish..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=ZX-Ishspectrum| image=N/A| homepage=Unknown| version=1.0| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/zx-ishpectrum_1.0.zip Plain Files]| release date=Unknown| author=Ishmair| original=N/A | systems=zx-spectrum 48k| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ishmair Version: 1.0 Last Updated: 11-27-01 Description: zx-spectrum 48k for the PAL dreamcast. Includes: * Own motor Z80 in assembler. * Motor of sound and graficos with also overscan (multiple colors in line) in assembler. * Contended memory emulated (it needs adjustments). * It supports to formats z80 v1, v2, v3 and sna of 48k, single load at the moment. * Trim of screen. * Single you need pad dreamcast to play, in fact it does not support the keyboard of dreamcast, as I do not have one I cannot program it, and I do not think to buy it. * Joystick kempston emulado en pad analogico y boton A. * Joystick kempston emulado en pad analogico y boton A. * Pad digital and bellboys X, and, b are redefinibles like any key of the spectrum. * START invokes menu. =Downloads= * 1.0 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/zx-ishpectrum_1.0.zip Plain Files] Selfboot:No 64kb [[category:Emulator]] 9740ef52a4793ddfb6b60537562e3669b1b832c5 Zigziggy 0 945 2110 2023-03-01T22:47:51Z Unknown user 0 Created page with "zigziggy (Vincent Penne) was a French Dreamcast programmer and released [[DCPlaya]] together with Benjamin Gerard. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprof..." wikitext text/x-wiki zigziggy (Vincent Penne) was a French Dreamcast programmer and released [[DCPlaya]] together with Benjamin Gerard. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=14548 zigziggy's profile on DCEmulation] *[http://sashipa.ben.free.fr/dcplaya/ DCPlaya website] 816a677dd5a3695d57e233ef7067116ff02cd19b Y2kode 0 946 2111 2023-03-01T22:49:15Z Unknown user 0 Created page with "y2kode was a Coding competition organized by [[Lik-Sang]]. [[GypPlay]] an [[Burritro]] were submitted for this competition. [http://archives.dcemulation.org/www.y2kode.com/ y..." wikitext text/x-wiki y2kode was a Coding competition organized by [[Lik-Sang]]. [[GypPlay]] an [[Burritro]] were submitted for this competition. [http://archives.dcemulation.org/www.y2kode.com/ y2kode.com] e76e99da2e53ece3b9026640eb5e6de2fa501fb0 2112 2111 2023-03-01T22:49:21Z Unknown user 0 wikitext text/x-wiki y2kode was a Coding competition organized by [[Lik-Sang]]. [[GypPlay]] and [[Burritro]] were submitted for this competition. [http://archives.dcemulation.org/www.y2kode.com/ y2kode.com] 108feb09be9f8c548e446fdb5a1e2eff4919560c GD-ROM 0 7 2113 1815 2023-03-01T22:56:59Z Unknown user 0 wikitext text/x-wiki The GD-ROM format is Sega's proprietary disc format used for the Sega Dreamcast home console, as well as for the arcade systems [[NAOMI]], [[NAOMI 2]], Triforce, and Chihiro. These discs contain a low density, linearly-read section, a security ring to verify authenticity, and an angularly-read high-density section. GD-ROMs usually contain a [[0GDTEX.PVR]] image that can be shown on the BIOS CD player screen. The most common GD-ROM image format is the [[GDI format]]. ==GD-R discs== [[File:GDR discs at Sega.jpg|400px|thumb|right|GD-R discs stored at Sega of America]] GD-R discs are the recordable version of Sega's proprietary disc format. GD-Rs lack the security ring between the standard density and high density sections, and thus only boot on a retail Dreamcast system using a [[System Disc 2]]. The [[Katana Dev.box]] will also play these discs. 17d73a447bfe041f5c7908e65ea5eedabd7daca0 NetBSD/Dreamcast 0 756 2114 1808 2023-03-01T23:02:09Z Unknown user 0 wikitext text/x-wiki NetBSD is a powerful, UNIX-based operating system with a Dreamcast port. Earlier versions of NetBSD for Dreamcast were partially maintained by SEGA employees. NetBSD for Dreamcast is an official port of NetBSD and includes BBA support, Video Support and Keyboard support. [[Marcus Comstedt]] also maintained NetBSD/Dreamcast. '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Building NetBSD source from scratch== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) ===Output directories=== * <code>~/netbsd/dest</code> will contain a copy of your NetBSD/Dreamcast userland. * <code>~/netbsd/release/dreamcast/binary</code> will contain packaged copies of kernels and userland sets for resharing with others. ==Kernel Options== ===NFS booting=== options NFS_BOOT_BOOTSTATIC options NFS_BOOTSTATIC_MYIP="\"192.168.0.100\"" options NFS_BOOTSTATIC_GWIP="\"192.168.0.1\"" options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" options NFS_BOOTSTATIC_SERVADDR="\"192.168.0.2\"" options NFS_BOOTSTATIC_SERVER="\"192.168.0.2:/home/user/netbsdmount\"" options NFS_BOOT_RWSIZE=1024 ad4505ee17828220c5d41c0782026b2ba2f7aeca 2115 2114 2023-03-01T23:02:48Z Unknown user 0 wikitext text/x-wiki NetBSD is a powerful, UNIX-based operating system with an official Dreamcast port. Earlier versions were partially maintained by Sega employees. NetBSD includes BBA support, Video Support and Keyboard support. [[Marcus Comstedt]] also maintained NetBSD/Dreamcast. '''This article is a WIP. It is subject to rapid change. Beware!''' Before building NetBSD, it's important to undertand [http://www.netbsd.org/releases/release-map.html release types] and pick one of release, stable, or current types. The example we'll follow here is using is using 10.0-release BETA. In general, the instructions are made to be able to copy/paste, but read the text before and after the commands to make sure you understand them in case you need to adjust paramaters to your liking. References: [https://www.netbsd.org/docs/guide/en/chap-fetch.html How to fetch NetBSD sources], [https://www.netbsd.org/docs/guide/en/chap-build.html How to build NetBSD] ==Building NetBSD source from scratch== ===Initial folder setup=== Create a working directory in your home folder to hold everything, and enter it: mkdir ~/netbsd cd ~/netbsd Create additional directories for files: mkdir obj toolchain dest release src-tars xsrc-tars ===Download files=== Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/src/ and place files into directory src-tars Download all files from ftp.netbsd.org/pub/NetBSD/NetBSD-release-10/tar_files/xsrc/ and place files into directory xsrc-tars ===Extract files=== cd ~/netbsd for file in src-tars/*.tar.gz; do tar -zxf $file; done for file in xsrc-tars/*.tar.gz; do tar -zxf $file; done ===Build toolchain=== First, we need to build the cross-compiler to compile SuperH code on your desktop machine. cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -m dreamcast tools (-U is unprivileged, -O is where to store object files, -T is your toolchain directory, -D is the directory to place built NetBSD files, -R is the directory to place release files, -j is number of threads during build, -m is machine type, tools indcates you want to build toolchain) Be sure to adjust -j to the number of threads you want to use depending on how many cores/threads your processor provides. ===Build kernel=== cd ~/netbsd/src/sys/arch/dreamcast/conf If your target Dreamcast is [[32MB RAM expansion|modded with 32MB of RAM]] and you wish to build for that, open <code>std.dreamcast</code> and replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB You can pick GENERIC, GENERIC_MD (memory disk), or G1ATA kernel types. You can also copy one of them to a new file in the same dir and edit to configure your own kernel options for a custom kernel type. If you have a serial or USB [[coder's cable]] and want to run headless, or don't have a Dreamcast keyboard and want to use your computer keyboard for input, you may want to set <code>options SCIFCONSOLE</code> in your kernel config to communicate over serial connection. Run nbconfig on your kernel config: ~/netbsd/toolchain/bin/nbconfig GENERIC Enter the configuration directory: cd ../compile/GENERIC Then build dependencies and kernel: ~/netbsd/toolchain/bin/nbmake-dreamcast depend ~/netbsd/toolchain/bin/nbmake-dreamcast netbsd.bin is your kernel file and Dreamcast executable (e.g. it can be sent over dcload-ip to boot NetBSD, or it can be scrambled and burned to CD-R as 1ST_READ.BIN). cp netbsd.bin ~/netbsd/NetBSD-10.0_BETA-GENERIC.bin You can repeat these steps to build multiple kernels. ===Build userland=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -j2 -u -m dreamcast release (-u is update-only so we use what we've already built before instead of building another toolchain, and don't forget -j is number of threads during build) ===Build X Server=== cd ~/netbsd/src ./build.sh -U -O ~/netbsd/obj -T ~/netbsd/toolchain -D ~/netbsd/dest -R ~/netbsd/release -x -X ~/netbsd/xsrc -j2 -u -m dreamcast release (-x is to build the X server, -X is the path of the X source code) ===Output directories=== * <code>~/netbsd/dest</code> will contain a copy of your NetBSD/Dreamcast userland. * <code>~/netbsd/release/dreamcast/binary</code> will contain packaged copies of kernels and userland sets for resharing with others. ==Kernel Options== ===NFS booting=== options NFS_BOOT_BOOTSTATIC options NFS_BOOTSTATIC_MYIP="\"192.168.0.100\"" options NFS_BOOTSTATIC_GWIP="\"192.168.0.1\"" options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" options NFS_BOOTSTATIC_SERVADDR="\"192.168.0.2\"" options NFS_BOOTSTATIC_SERVER="\"192.168.0.2:/home/user/netbsdmount\"" options NFS_BOOT_RWSIZE=1024 1365a04789e98123b93f3e06273208081431ac90 Save/Load file 0 948 2117 2023-03-01T23:09:35Z Unknown user 0 Created page with "= VMU = The following code will demonstrate how to write a compressed file to the VMU using [[KallistiOS]]. It is possible to just write raw data to the VMU, but in order for..." wikitext text/x-wiki = VMU = The following code will demonstrate how to write a compressed file to the VMU using [[KallistiOS]]. It is possible to just write raw data to the VMU, but in order for the file to show up properly in the VMU menu, a VMU package header with a description and icon is specified as well. The following headers are required for the VMU header and compression. #include <kos.h> #include <zlib/zlib.h> == Saving == The save function will write to the first controller's first VMU. int DC_SaveToVMU(char *src) { char dst[32]; file_t file; int filesize = 0; unsigned long zipsize = 0; uint8 *data; uint8 *zipdata; vmu_pkg_t pkg; uint8 *pkg_out; int pkg_size; // Our VMU + full save name strcpy(dst, "/vmu/a1/"); strcat(dst, src); // Reads in the file from the CWD file = fs_open(src, O_RDONLY); filesize = fs_total(file); data = (uint8*)malloc(filesize); fs_read(file, data, filesize); fs_close(file); // Allocate some memory for compression zipsize = filesize * 2; zipdata = (uint8*)malloc(zipsize); // The compressed save compress(zipdata, &zipsize, data, filesize); // Required VMU header // You will have to have a VMU icon defined under icon_data strcpy(pkg.desc_short, "Wolf4SDL\\DC"); strcpy(pkg.desc_long, "Game Save"); strcpy(pkg.app_id, "Wolf4SDL\\DC"); pkg.icon_cnt = 1; pkg.icon_anim_speed = 0; memcpy(&pkg.icon_pal[0], icon_data, 32); pkg.icon_data = icon_data + 32; pkg.eyecatch_type = VMUPKG_EC_NONE; pkg.data_len = zipsize; pkg.data = zipdata; vmu_pkg_build(&pkg, &pkg_out, &pkg_size); // Save the newly created VMU save to the VMU fs_unlink(dst); file = fs_open(dst, O_WRONLY); fs_write(file, pkg_out, pkg_size); fs_close(file); // Free unused memory free(pkg_out); free(data); free(zipdata); return 0; } == Loading == int DC_LoadFromVMU(char *dst) { char src[32]; int file; int filesize; unsigned long unzipsize; uint8* data; uint8* unzipdata; vmu_pkg_t pkg; // Our VMU + full save name strcpy(src, "/vmu/a1/"); strcat(src, dst); // Remove VMU header file = fs_open(src, O_RDONLY); if(file == 0) return -1; filesize = fs_total(file); if(filesize <= 0) return -1; data = (uint8*)malloc(filesize); fs_read(file, data, filesize); vmu_pkg_parse(data, &pkg); fs_close(file); // Allocate memory for the uncompressed data unzipdata = (uint8 *)malloc(65536); unzipsize = 65536; // Uncompress the data to the CWD uncompress(unzipdata, &unzipsize, (uint8 *)pkg.data, pkg.data_len); fs_unlink(dst); file = fs_open(dst, O_WRONLY); fs_write(file, unzipdata, unzipsize); fs_close(file); // Free unused memory free(data); free(unzipdata); return 0; } f2eeff0838493bd77269e02af7ddd63e31b4c83b Development 0 2 2118 1922 2023-03-01T23:13:30Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** KMG Textures === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] f53dc8fc0648d000a197bc45c27b628437d6880c 2119 2118 2023-03-01T23:13:38Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 61a9ea9dc4b18f8fc2f8178e3c621d0e814ce340 2121 2119 2023-03-01T23:14:50Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] e3778e859ca7822f682f103c3073533edaca26bd 2128 2121 2023-03-02T00:51:32Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === [[Graphics APIs]] * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] cbc665679752ad36189d25e15eb451ad3f3589e1 2130 2128 2023-03-02T00:54:23Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === [[Texture Formats]] [[Graphics APIs]] * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] c2fa529ff3d4daefff67fe2c1ae8ba8ee269f07b 2133 2130 2023-03-02T01:04:23Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 2dbcf8601db4752cc971bb7dcd5b8da7aeca719a 2135 2133 2023-03-02T01:05:32Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 1fdcf2576daed003d4bc20d0c67824cbac8504ae 2137 2135 2023-03-02T01:06:36Z Unknown user 0 /* Graphics */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on BSD]] * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on GNU/Linux]] * [[Building the required toolchains on macOS]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] 8c39915fa4eaf22b9b83059684a72ead8a4d3269 2142 2137 2023-03-02T01:08:42Z Unknown user 0 /* Building the required toolchains for Sega Dreamcast development */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== * [[Building the required toolchains on Cygwin]] * [[Building the required toolchains on MinGW/MSYS]] * [[Building the required toolchains on MinGW-w64/MSYS2]] ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] f7b2d803a788632773b9c960e49f22fe9d41f384 2143 2142 2023-03-02T01:09:13Z Unknown user 0 /* Getting started */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Random Snippets === * [[Objdump]] e80687df87e46c15d8284237fdea884d72b252d5 KMG Textures 0 949 2120 2023-03-01T23:13:47Z Unknown user 0 Created page with "= About KMG files = There are many image file formats out there. First of all the image data may be encoded in various ways. For example the pixel format could be RGB565 or A..." wikitext text/x-wiki = About KMG files = There are many image file formats out there. First of all the image data may be encoded in various ways. For example the pixel format could be RGB565 or ARGB4444. Furthermore the image data may be paletted, twiddled or compressed. The image may also come with mipmaps (smaller versions of itself). The mipmaps could be stored from small to big or big to small, with padding, etc. Lastly, meta information such as the dimensions, used pixel format, how many mipmaps are available, whether compression was applied, etc. must be stored somehow. Therefore, instead of just storing the raw image data, so called ''container formats'' are used. KOS provides an image container format called ''[http://gamedev.allusion.net/docs/kos-current/structkos__img.html KMG]''. You are in no way forced to use this format and may want to create your own for advanced use cases, but it gets the basic job done and comes with convenient functions and a conversion program in KOS. This tutorial will explain how to convert images to Dreamcast-friendly formats and pack them into a KMG container file. It will then explain how to load the data into memory, ready to be used in drawing code. = Conversion = == Directory setup == In your project's folder, you should create a folder named ''assets'' and another one named ''romdisk'' (names can be changed). ''assets'' will contain your raw image files. ''assets/foo.png'' will be converted to ''romdisk/foo.kmg''. The raw asset files are put into a different directory, because only the converted files will be used in the game and the raw asset files would only take up space. == Makefile rules == Makefiles describe a dependency graph to only rebuild files that were changed. This is useful because converting all our image files all the time, although they haven't changed, would take a lot of build time. In our case the dependency graph for our game might look like the following: image1.png --> image1.kmg -\ image2.png --> image2.kmg --+--> romdisk.img --> romdisk.o --+--> game.elf image3.png --> image3.kmg -/ main.c --> main.o ----/ So when ''image2.png'' is changed by an artist, only ''image2.kmg'' is regenerated using the ''vqenc'' conversion tool, which leads to regenerating ''romdisk.img'' which leads to regenerating ''romdisk.o''. Let's look at the ''Makefile rules'' to describe this process starting from the back. === Makefile rule syntax === The general syntax is target_file: dependency_file1 dependency_file2 <TAB>shell commands For a full introduction to ''Make'' please refer to [https://www.gnu.org/software/make/manual/make.html#Introduction] === romdisk.o rule === This rule will convert ''romdisk.img'' to ''romdisk.o'' which can be passed to ''gcc'' during compilation (kos-cc main.o romdisk.o -o game.elf) romdisk.o: romdisk.img $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o === romdisk.img rule === This rule gathers a list of filenames of the form ''assets/*.png''. It will then convert this list into the form ''romdisk/*.kmg''. The generated kmg filename list is then used as the list of required files for ''romdisk.img''. ''genromfs'' is told to put the directory ''romdisk'' into romdisk.img romdisk.img: $(patsubst ''assets''/%.png,''romdisk''/%.kmg,$(wildcard ''assets''/*.png)) $(KOS_GENROMFS) -f romdisk.img -d romdisk -v The converted image files will be available as ''/rd/foo.kmg'' during runtime. === ELF building rule === This rule gathers up all of the built object files of the program and links them with any necessary libraries to produce a .elf file that can be run. First, define the target for your build and all the object files that are required for the binary. Put this little bit of setup work up at the top of your Makefile: $(TARGET) = test.elf $(OBJS) = main.o romdisk.o all: rm-elf $(TARGET) include $(KOS_BASE)/Makefile.rules rm-elf: -rm -f $(TARGET) romdisk.* Then, add the build target to create your actual binary from the built object files, like so: $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -lkmg -lkosutils You will need to build libkmg in kos-ports if you have not already done so in order to build your program. === PNG to KMG conversion rule === Next we need to call a program to actually convert foo.png to foo.kmg. KOS provides an image data conversion tool that can optionally put the resulting data in the KMG container format. You can find it in the folder kos/utils/vqenc. Usage: vqenc [options] image1 [image2..] Options: -t, --twiddle create twiddled textures -m, --mipmap create mipmapped textures (EXPERIMENTAL) -v, --verbose verbose -d, --debug show debug information -q, --highq higher quality (much slower) -k, --kmg write a KMG for output -a, --alpha use alpha channel (and output ARGB4444) -b, --amask use 1-bit alpha mask (and output ARGB1555) The following Makefile rule should be added to use it to convert images: ''romdisk''/%.kmg: ''assets''/%.png $(KOS_BASE)/utils/vqenc/vqenc -v -t -q -k $< mv assets/$*.kmg romdisk/ -v will turn on verbose conversion information and give you some additional insight. -t will reorder the pixels into the order the PVR graphics chip can render the fastest. -q will tell the conversion program that it can take its time to perform a better VQ compression. -k will save the converted and compressed image data in a .kmg file. Otherwise it will create a .vq file without meta information which you could use in your own image container format. Since vqenc does not accept a destination directory name, the result is moved to the romdisk directory manually. In Make, ''$*'' represents the result of the ''%'' placeholder in the rule line. After typing make you should see that ''foo.kmg'' is put into the romdisk, but ''foo.png'' is not. = Loading = To gain access to the romdisk and read files in the ''romdisk'' directory as ''/rd/foo.kmg'', you need to add the following: extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); The loading function will load the texture and put its content into video memory. #include <kos/img.h> #include <kmg/kmg.h> #include <dc/pvr.h> #include <stdio.h> pvr_ptr_t load_kmg(char const* filename, uint32* w, uint32* h, uint32* format) { kos_img_t img; pvr_ptr_t rv; if(kmg_to_img(filename, &img)) { printf("Failed to load image file: %s\n", filename); return NULL; } if(!(rv = pvr_mem_malloc(img.byte_count))) { printf("Couldn't allocate memory for texture!\n"); kos_img_free(&img, 0); return NULL; } pvr_txr_load_kimg(&img, rv, 0); kos_img_free(&img, 0); *w = img.w; *h = img.h; *format = img.fmt; return rv; } Usage in main(): int main() { /* ... */ uint32 w, h, format; pvr_ptr_t txr = load_kmg("/rd/image.kmg", &w, &h, &format); if(txr) printf("Loaded /rd/image.kmg with dimensions %ux%u, format %u\n", w, h, format); } You can now use the PVR API to draw this texture. abcdde8b11ce6a2313868c4e4a0215c4581ca43f File:Kos gl png tutorial.png 6 950 2122 2023-03-01T23:15:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Kos gl png tutorial}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a613fcdf727de7a71648953e4f87ede61d64942c File:Kos gl png tutorial.zip 6 951 2123 2023-03-01T23:15:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Kos gl png tutorial}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a613fcdf727de7a71648953e4f87ede61d64942c Loading PNG images as OpenGL textures 0 952 2124 2023-03-01T23:16:07Z Unknown user 0 Created page with "= Introduction = In this tutorial you will learn how to load a PNG file and display it using OpenGL. This is the finished result: [[File:Kos gl png tutorial.png]] Please not..." wikitext text/x-wiki = Introduction = In this tutorial you will learn how to load a PNG file and display it using OpenGL. This is the finished result: [[File:Kos gl png tutorial.png]] Please note that it is recommended to use compressed textures instead to save some memory. However, this tutorial should be useful to get you started with drawing things on the screen. You can find more information about this optimization in the [http://dcemulation.org/?title=Texture_Formats "Texture Formats" article] = Overview = Loading a texture in OpenGL consists of two phases. == Loading the image file into memory == Given an image file, parse its meta information (dimensions, color format) and get an array of pixel values. In this tutorial ''libpng'' will be used to parse PNG image files. libpng has a really terrible API, but all we basically need it to do is give us the width, height, color format and pixel values. == Upload to the graphics chip == Although the texture has been parsed it's not ready for drawing yet. It first needs to get transferred from main memory to video memory (on the graphics chip). The OpenGL API offers the function ''glTexImage2D'' to perform this upload. Make sure to read the [https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glTexImage2D.xml documentation of glTexImage2D]. It is declared as follows: void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data) ''data'' is the argument for the pixel values, ''width'', ''height'' and ''format'' (e.g. RGBA) are also obtained via ''libpng''. While loading the image file, libpng will be told to convert various image formats to RGB or RGBA, depending on whether they have transparency information. This way the loading code can deal with palettes, grayscale, 16 bit per color channel and transparent color masks as well. = Implementation = == Loading the PNG file == In the end we want to fill the following data structure: struct texture { GLuint id; GLenum format; GLenum min_filter; GLenum mag_filter; uint16_t w, h; }; The ''id'' is a handle to the OpenGL driver's texture. This way the texture can be activated with the ''glBindTexture'' function ([https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glBindTexture.xml documentation of glBindTexture]). The following function is to be implemented: int png_to_gl_texture(struct texture * tex, char const * const filename) { It will return an error code with 0 representing ''no error''. There are many possible error conditions and it must be ensured that memory is freed properly, so the code will set an error code and jump to a ''cleanup'' label at the end of the function and make sure to free all memory even on error. int ret = 0; FILE * file = 0; uint8_t * data = 0; png_structp parser = 0; png_infop info = 0; png_bytep * row_pointers = 0; png_uint_32 w, h; int bit_depth; int color_type; if(!tex || !filename) { CLEANUP(1); } file = fopen(filename, "rb"); if(!file) { CLEANUP(2); } The following code sets up some state for ''libpng'' to use during parsing. libpng uses setjmp to return from an error (which is a terrible design decision on their part, don't imitate this in your APIs). parser = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if(!parser) { CLEANUP(3); } info = png_create_info_struct(parser); if(!info) { CLEANUP(4); } if(setjmp(png_jmpbuf(parser))) { CLEANUP(5); } Here the meta information of the image file is read. PNG images with dimensions that are not powers of two or smaller than 8 are forbidden because the graphics chip cannot handle them. If you would like to use a texture with dimensions such as 100x50, then you will have to resize it to 128x64 using an image editing program, or you will have to make the loading code more complicated and put the 100x50 image into a 128x64 texture. You may also use strided textures. png_init_io(parser, file); png_read_info(parser, info); png_get_IHDR(parser, info, &w, &h, &bit_depth, &color_type, 0, 0, 0); if((w & (w-1)) || (h & (h-1)) || w < 8 || h < 8) { CLEANUP(6); } The following code instructs ''libpng'' to transform various image formats to RGB/RGBA with 8 bits per color channel. if(png_get_valid(parser, info, PNG_INFO_tRNS) || (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) || color_type == PNG_COLOR_TYPE_PALETTE) { png_set_expand(parser); } if(bit_depth == 16) { png_set_strip_16(parser); } if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(parser); } png_read_update_info(parser, info); int rowbytes = png_get_rowbytes(parser, info); rowbytes += 3 - ((rowbytes-1) % 4); // align to 4 bytes data = malloc(rowbytes * h * sizeof(png_byte) + 15); if(!data) { CLEANUP(6); } row_pointers = malloc(h * sizeof(png_bytep)); if(!row_pointers) { CLEANUP(7); } // set the individual row_pointers to point at the correct offsets of data for(png_uint_32 i = 0; i < h; ++i) { row_pointers[h - 1 - i] = data + i * rowbytes; } png_read_image(parser, row_pointers); At this point we're finally done with ''libpng'' and have the image's meta information as well as image data. Now the texture needs to be uploaded to OpenGL. GLuint texture_id; glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); GLenum texture_format = (color_type & PNG_COLOR_MASK_ALPHA) ? GL_RGBA : GL_RGB; glTexImage2D(GL_TEXTURE_2D, 0, texture_format, w, h, 0, texture_format, GL_UNSIGNED_BYTE, data); In the end the result is stored in the texture struct that we defined earlier. By default no texture filter is used. tex->id = texture_id; tex->w = w; tex->h = h; tex->format = texture_format; tex->min_filter = tex->mag_filter = GL_NEAREST; This is the cleanup label that was mentioned earlier. All the temporary memory is freed and on error the image data is freed as well. cleanup: if(parser) { png_destroy_read_struct(&parser, info ? &info : 0, 0); } if(row_pointers) { free(row_pointers); } if(ret && data) { free(data); } if(file) { fclose(file); } return ret; } == Drawing == The following code demonstrates how to activate the texture and draw a simple rectangle with the texture applied to it. === Main function === OpenGL is initialized using ''glKosInit'' on the Dreamcast. The default coordinate system extends horizontally and vertically between -1 and +1, with (x=0,y=0) at the center. Here it is first moved into a corner and then scaled to make it go between [0,640]x[0,480] instead (screen dimensions). This is generally what you want for a 2D game. int main(int argc, char **argv) { glKosInit(); glTranslatef(-1.f, -1.f, 0.f); glScalef(1.f/320.f, 1.f/240.f, 1.f); The file ''/rd/image.png'' is loaded into ''struct texture tex''. Later, ''tex'' is used to activate the texture when drawing. struct texture tex; int ret = png_to_gl_texture(&tex, "/rd/image.png"); if(ret) { printf("Cannot load texture, error code %d.\n", ret); return 1; } In the endless main loop the texture is drawn centered on the screen. A function called ''draw_textured_quad'' is used for this purpose and will be explained later. for(;;) { float x = (640 - tex.w) / 2.f; float y = (480 - tex.h) / 2.f; draw_textured_quad(&tex, x, y); glutSwapBuffers(); } return 0; } === Drawing a textured rectangle === Above, the function ''draw_textured_quad'' is used. This function is defined as follows: void draw_textured_quad(struct texture const * const tex, float x0, float y0) { ''x0'' and ''y0'' are passed in as arguments and represent the start of the rectangle. The ''width'' and ''height'' of the texture are taken from the texture object ''tex'' and added to these coordinates to obtain ''x1'' and ''y1''. float x1 = x0 + tex->w; float y1 = y0 + tex->h; Next, OpenGL is told the geometry of what's going to be drawn. For a rectangle 4 points are required. Since the rectangle is supposed to be textured, OpenGL also needs to know how to apply the texture to its geometry. This is done by using ''texture coordinates'' which go from 0.0 to 1.0. float const vertex_data[] = { /* 2D Coordinate, texture coordinate */ x0, y1, 0.f, 1.f, x0, y0, 0.f, 0.f, x1, y1, 1.f, 1.f, x1, y0, 1.f, 0.f, }; Now texturing is enabled and the ''texture id'' in ''tex'' is bound. We also apply the filtering that was set up for this texture. glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex->id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter); All the geometry information has been assembled and the texture is active. Now OpenGL is told what is contained in the ''vertex_data'' (position + texture coordinates). glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer (2, GL_FLOAT, 4 * sizeof(float), vertex_data); glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), vertex_data + 2); This command will send a draw command to the graphics chip. It starts with the first point (0) and draws 4 points in total. ''GL_TRIANGLE_STRIP'' uses triangle strips to draw the points. For 4 points this results in a rectangle. You can read more about triangle strips in the [https://en.wikipedia.org/wiki/Triangle_strip Wikipedia triangle strip article]. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); In the end the enabled ''client states'' are disabled again, just in case other code assumes it to be disabled. glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } = Download = You can download the tutorial as a ZIP archive including an example image and compiled Dreamcast ELF binary here: [[File:Kos gl png tutorial.zip]]. 3e6d8184d28323345a1d35cfd26665525c77d501 Windows CE 0 953 2125 2023-03-01T23:18:41Z Unknown user 0 Created page with "Windows CE is an operating system that was intended for embedded devices such as PDAs. Windows CE for the Dreamcast is a development library developed by Microsoft that was me..." wikitext text/x-wiki Windows CE is an operating system that was intended for embedded devices such as PDAs. Windows CE for the Dreamcast is a development library developed by Microsoft that was meant to ease the conversion process between Windows programs and Dreamcast programs. Despite the "compatible with Microsoft Windows CE" mark on the right side Dreamcast consoles, the entire operating system is not present on the Dreamcast, and Windows CE is not embedded into the system as it is with most other Windows CE enabled devices. Most commercial games do not use Windows CE, and use the Sega-created development library, [[Katana]], instead, which was also used in the Naomi and Naomi2 arcade boards. Around 50 games use Windows CE for Dreamcast and a few scene and homebrew releases. '''Software releases using Windows CE for Dreamcast:''' *[[Half-Life]] (Bootleg) *[[QuakeDC]] (Titanium Studios, Freeware) *[[Defense Commander]] (Titanium Studios, Freeware) *[[PBA Bowling]] (Bootleg) *[[Retro Sonic]] (Freeware) *[[GypPlay]] (Freeware) *[[Boob!play]] (Freeware) *[[Sintendo]] (Freeware) 8fe2a3716d651d788aebfd4cabc9987ed7d48b6c Asteroids 0 954 2126 2023-03-02T00:49:23Z Unknown user 0 Created page with "Developer: [http://jimbomania.com Jimbo] Version: 0.0.7 Last Updated: March 28, 2002 Description: A 3D version of Asteroids for the Dreamcast. [http://www.dcemulation...." wikitext text/x-wiki Developer: [http://jimbomania.com Jimbo] Version: 0.0.7 Last Updated: March 28, 2002 Description: A 3D version of Asteroids for the Dreamcast. [http://www.dcemulation.org/files/software/dihbNero.zip Nero Image] [http://www.dcemulation.org/files/software/dihbDJ.zip Disc Juggler] [http://www.dcemulation.org/files/software/dcasteroids007.zip Plain Files] e7aa702f183e1723f34a75ecdeba10996dde20a9 Adrian O'Grady 0 955 2127 2023-03-02T00:50:16Z Unknown user 0 Created page with "Adrian O'Grady was an active contributor to the [[LinuxDC]] project. He was also involved in the GBA scene. His blog, fivemouse.com, disappeared in 2006, after 4 years without..." wikitext text/x-wiki Adrian O'Grady was an active contributor to the [[LinuxDC]] project. He was also involved in the GBA scene. His blog, fivemouse.com, disappeared in 2006, after 4 years without any update. 8c02f0d5af00bf26e1ece2e8f62c2060c62ec01e Graphics APIs 0 956 2129 2023-03-02T00:53:12Z Unknown user 0 Created page with "In KOS there are three major ways of drawing things on the screen. == Software rendering == Software rendering means drawing is performed using the Dreamcast's "SH4" CPU only..." wikitext text/x-wiki In KOS there are three major ways of drawing things on the screen. == Software rendering == Software rendering means drawing is performed using the Dreamcast's "SH4" CPU only, not the "PVR" graphics chip. After configuring the video screen you can write to the screen's memory area directly. '''Advantages''' * Flexible: You can emulate a simple blitter, an NES-like sprite renderer, a raytracer, a photon mapper and other methods the Dreamcast graphics chip doesn't support. * Simple '''Disadvantages''' * Slow * You have to implement a complete renderer yourself == OpenGL == OpenGL is a cross-platform graphics programming interface. Earlier implementations of OpenGL in KOS were slow and incomplete, but recent work by PH3NOM and kazade over the past years have culminated in the much more performant GLdc. '''Advantages''' * Cross-platform: OpenGL code written for the Dreamcast should mostly work on other platforms as well (barring bugs which should be fixed) and vice versa, which makes porting existing software easier. * Familiar: If you've programmed OpenGL before you will feel right at home. There are many tutorials and books outside of the DC homebrew scene. * Fast: OpenGL is implemented as a thin layer on top of the low-level PVR API. It will be difficult to outperform it without in-depth PVR API/hardware knowledge and major effort. '''Disadvantages''' * Only fixed-pipeline OpenGL version ~1.5 (no shaders) is supported due to hardware limitations, although some modern extensions are supported (e.g. FBO) * Since the Dreamcast PVR graphics chip is a tile-based raycaster instead of the usual rasterizer approach (NVIDIA/ATI GPUs etc.), some operations don't map to OpenGL very well (e.g. multipass rendering should be used instead of the non-existant z-buffer, scissoring is awkward). == PVR API == The PVR API is the low-level graphics programming interface in KOS for the PVR graphics chip. It exposes all the features the Dreamcast has to offer. '''Advantages''' * Fast: For specific niche cases that the OpenGL API doesn't cover well you might be able to outperform it * Direct access to all PVR graphics chip features. E.g. OpenGL has no concept for PVR "occlusion volumes". '''Disadvantages''' * Lacking in features: The PVR API is very bare bones. You will have to implement basic functionality such as polygon clipping yourself. * Non-obvious: There are many ways to do certain things like geometry submission and you will have to experiment a lot in order to obtain good performance. * Learning curve: You have to learn a new API that is only used on the Dreamcast 45aa9a91768729b6b9bc0f8c48bfb528e8738f77 VMU development 0 99 2131 1920 2023-03-02T00:55:10Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual efc491aa837477c3f2ecbc1ee4f3fc0177f0d41f Texture Formats 0 957 2132 2023-03-02T00:55:17Z Unknown user 0 Created page with "This tutorial will explain how you can store image data on the Dreamcast's PVR graphics chip for efficient drawing and compact storage. [https://kos-docs.dreamcast.wiki/group..." wikitext text/x-wiki This tutorial will explain how you can store image data on the Dreamcast's PVR graphics chip for efficient drawing and compact storage. [https://kos-docs.dreamcast.wiki/group__pvr__txr__fmts.html List of texture formats] = Color formats = == Truecolor == This table describes the color information that can be stored in textures. {|RGB565 || 5 bits of red, 6 bits of green, 5 bits of blue, no transparency |- |ARGB1555 || each color channel has 5 bits, transparency is on or off |- |ARGB4444 || each channel has 4 bits, use if you need a transparent gradient |- |BUMP || bumpmap format (stores angles for vertex displacement effects in lighting calculations), similar to a normal map |- |YUV422 || mostly used for video decoding, uncommonly used |} == Paletted == There are also paletted texture formats which can be combined with the above color formats as well as ARGB8888. 4BPP_PAL (or 8BPP_PAL) # Define an array of 2^4 = 16 (or 2^8 = 256) color values. # Copy the array to the graphics chip, then send textures that use 4-bit (or 8-bit) indices into that array instead of 16 bit argb as pixel values. ARGB8888 is slow when used with filtering. You can set multiple palettes on the graphics chip at the same time (1024 bytes total), so they're not per-texture at all, but global. Paletted textures are always twiddled and never strided. = Additional attributes = Textures can be twiddled, VQ compressed, strided or mipmapped. == Twiddled == Pixels aren't stored row-by-row, but in a z-shape arrangement which puts neighboring pixels closer together. This makes texture filtering cheaper and you definitely want to use it. Twiddled textures must have power-of-two dimensions (e.g. 512x512, 256x1024). == VQ compressed == Vector Quantization is a lossy texture compression. The Dreamcast graphics chip has special hardware to decode it, so you suffer no performance loss for the decoding step when texture data is read by it for drawing. Textures will use less video memory. == Strided == A way to draw non-power-of-two textures by defining gaps. == Mipmapped == Each texture stores smaller versions of itself (512x256 -> 256x128 -> 128x64..). Makes textures 1/3 bigger, texture filtering cheaper and improves rendering performance when textures are displayed at a smaller than original size. = Converting art assets to Dreamcast texture formats = It is more efficient to convert your PNG/TGA/etc. art assets during the build process of your game instead of during runtime. There are tools for conversion in the KOS utils folder. Be aware that the KOS conversion tool does not support non-square VQ textures, although it should. This conversion tool by tvspelsfreak offers support for that in addition to a handy preview feature [[https://github.com/tvspelsfreak/texconv]] = Comparison between uncompressed and compressed = To see how useful applying the proper texture format is, check out [http://dcemulation.org/phpBB/viewtopic.php?f=29&t=103369&p=1045482 this thread] Consider face.png, 1024x1024, RGB888 for example. * 304K face.png * 3.1M face.tga * 516K face.dds * 344K face.kmg * 108K face.kmg.gz If you store this texture on the CD as PNG, it will will take 304 kilobytes. After unpacking it and storing it in video memory it will take 3 megabytes (1024*1024 * 3 bytes = 3 MB). If you convert it from RGB888 to RGB565 it will still take 2 megabytes. The VQ compressed RGB565 texture takes 344 kilobytes in video memory. No decompression is required, it is quicker to upload to the PVR graphics chip and requires 6 times less video memory. Depending on the amount of colors in the original image the quality loss may not be noticeable. 019a459bb60154f2193aae7a49cdf12441d25b3a Paletted Textures 0 958 2134 2023-03-02T01:04:34Z Unknown user 0 Created page with "= Specifying a palette = The PVR graphics chip has an internal bank of color palette entries. This bank contains a total of 1024 color entries, each of which is 32 bits wide (..." wikitext text/x-wiki = Specifying a palette = The PVR graphics chip has an internal bank of color palette entries. This bank contains a total of 1024 color entries, each of which is 32 bits wide (no matter what truecolor format you choose). The color palette can be configured in three modes which match the format of the standard 16-bit textures: ARGB1555, ARGB4444, RGB565. There's also a 32-bit mode, which allows you to use ARGB8888 colour palette entries. The palette mode is a global setting - it affects all rendering of paletted textures. So it's a good idea to set this to something that fills all your paletted texture needs. To set the palette format, you use the pvr_set_pal_format function, with one of the PVR_PAL_ values. For example, to set up an ARGB8888 palette: pvr_set_pal_format(PVR_PAL_ARGB8888); To set a colour palette entry, use the pvr_set_pal_entry function. This function takes a palette index from 0 to 1023, and a colour value. The colour value is in whatever format you set the palette to. In our case, that's ARGB8888. So, to set the first four palette entries to transparent, black, white, and red, we could do something like this: #define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) ) pvr_set_pal_entry(0, PACK_ARGB8888(0, 0, 0, 0)); pvr_set_pal_entry(1, PACK_ARGB8888(255, 0, 0, 0)); pvr_set_pal_entry(2, PACK_ARGB8888(255, 255, 255, 255)); pvr_set_pal_entry(3, PACK_ARGB8888(255, 255, 0, 0)); There are 1024 colour palette entries. If you're using 4bpp images (16 colours each), you treat this as 64 separate 16 colour palettes. Palette 0 consists of colours 0 through 15, palette 1 consists of colours 16 through 31, and so on. For 8bpp images, you get four 256 colour palettes, with palette 0 being colours 0 through 255, palette 1 being colours 256 through 511, and so on. We'll cover how to select which palette to use later. If you do not set a palette, you end up with palette 0. =Loading textures= You can load a paletted texture in the normal way, using pvr_txr_load_ex. You just need to make sure they're twiddled, which pvr_txr_load_ex will do for you. Actually loading texture data is a bit trickier than it could be - the utility functions in KOS to load textures automatically convert everything to 16bpp RGB565, which is obviously not what we want. I might post some sample code for reading a paletted image later. Most likely, either a PNG, PCX, or BMP file. But for now, just assume that you've managed to load an 8bpp image from somewhere... void *image_data; pvr_ptr_t texture_pointer; int width, height; To load an 8bpp image... pvr_txr_load_ex(image_data, texture_pointer, width, height, PVR_TXRLOAD_8BPP); To load a 4bpp image... pvr_txr_load_ex(image_data, texture_pointer, width, height, PVR_TXRLOAD_4BPP); =Using paletted textures= Now that we've come this far, we get to the easy part - using the textures. To use a paletted texture, you just need to specify the texture format when building the polygon header. For example, for an 8-bit texture with no filtering, using the default palette, and being rendered into the punch-through display list: pvr_poly_hdr_t hdr; pvr_poly_cxt_t cxt; pvr_poly_cxt_txr(&cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP, width, height, texture_pointer, PVR_FILTER_NONE); pvr_poly_compile(&hdr, &cxt); Same deal for 4bpp textures - just substitude PVR_TXRFMT_PAL4BPP. = Choosing a different palette = If you want to use something other than the default palette, you need to use the PVR_TXRFMT_8BPP_PAL and PVR_TXRFMT_4BPP_PAL macros: pvr_poly_cxt_txr(&cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(1), width, height, texture_pointer, PVR_FILTER_NONE); The numbers passed to PVR_TXRFMT_xBPP_PAL are palette numbers, not indexes. So in this example, the texture will use the second 256 colour palette, consisting of palette entries 256 through 511. = Why bother? = The main reason is memory usage. An 8bpp image takes up half as much video RAM as a 16bpp image, and a 4bpp image takes up half as much again. This is useful for 2D games, particularly if the source images use colour palettes anyway. You also get the ability to do palette animation, and use the same image multiple times with different colour palettes. These are tricks that a lot of old console games used to use to get animation from static images, and to provide a bit of variety to the graphics without needing to include more graphics data. You can also use paletted images for fonts. The ROM fonts are natively 4bpp images. Typically, we would convert them to a 16bpp ARGB4444 image, with the colour of every pixel set to white. That's a huge waste of memory, when we could just load the font as a 4bpp texture. In fact, anywhere you might use an ARGB4444 texture with all the colours set to white can be replaced with a 4bpp texture. It's also useful for simulating luminance-only and alpha-only textures. You can simulate a luminance-only (greyscale) texture by using an 8bpp image, and setting colour palette entry i to ARGB(255, i, i, i). Similarly, you can simulate an alpha-only texture by setting colour palette entry i to ARGB(i, 255, 255, 255). By itself, this isn't necessarily useful, since the PVR's framebuffer is only 5 or 6 bits per colour channel. However, if you combine this with blending, you can eliminate a lot of the rendering artefacts you'd get by using an ARGB4444 texture. For example, you might have a particle texture which is coloured by setting the vertex colours, and blended onto the scene, or a lightmap. Since the PVR renders everything internally in 32bpp, and only converts to RGB565 as the final step, rendering quality would be improved. aef96eaf359670a434bd29059134ad9510128715 2D Rendering Without PVR 0 959 2136 2023-03-02T01:05:43Z Unknown user 0 Created page with "<b>By [mailto:obsidianglow@NOSPAMhotpop.com BlackAura]</b> <h1>The basics</h1> <h2>Setting up a video mode</h2> <p>The first thing you should do when doing any kin..." wikitext text/x-wiki <b>By [mailto:obsidianglow@NOSPAMhotpop.com BlackAura]</b> <h1>The basics</h1> <h2>Setting up a video mode</h2> <p>The first thing you should do when doing any kind of graphics programming is set up a video mode. On the Dreamcast, this isn't really that important - KallistiOS will automatically set the video hardware up into 640x480, 16 bit 60Hz mode. However, it's still a good idea to set the video mode manually, in case they change something.</p> <p>This couldn't really be much simpler - we just need to call the function vid_set_mode, giving it our desired resolution and colour mode, and it'll do the rest:</p> <pre>vid_set_mode(display_mode, pixel_mode);</pre> <p>display_mode can be one of:</p> <table cols="4" rows="11" border="1"> <tr> <td>display_mode</td><td>Width</td><td>Height</td><td>Refresh rate</td> </tr> <tr> <td>DM_320x240</td><td>320</td><td>240</td><td>60Hz, VGA</td> </tr> <tr> <td>DM_640x480</td><td>640</td><td>480</td><td>60Hz, VGA</td> </tr> <tr> <td>DM_256x256</td><td>256</td><td>256</td><td>60Hz</td> </tr> <tr> <td>DM_768x480</td><td>768</td><td>480</td><td>60Hz</td> </tr> <tr> <td>DM_768x576</td><td>768</td><td>576</td><td>60Hz</td> </tr> <tr> <td>DM_640x480_PAL_IL</td><td>640</td><td>480</td><td>50Hz</td> </tr> <tr> <td>DM_256x256_PAL_IL</td><td>256</td><td>256</td><td>50Hz</td> </tr> <tr> <td>DM_768x480_PAL_IL</td><td>768</td><td>480</td><td>50Hz</td> </tr> <tr> <td>DM_768x576_PAL_IL</td><td>768</td><td>576</td><td>50Hz</td> </tr> <tr> <td>DM_800x608</td><td>800</td><td>608</td><td>VGA Only</td> </tr> </table> <p>The 60Hz modes will always be 60Hz, even on a PAL Dreamcast. The 50Hz modes will always be 50Hz, even on an NTSC Dreamcast. While most PAL TVs can display a 60Hz signal, some can not, and virtually no NTSC TVs can display a 50Hz signal. It's usually safe to use the 60Hz modes, but you might want to put in an option to use 50Hz on PAL Dreamcasts for those European gamers with old TVs. I'll go into more detail on that later.</p> <p>One rather strange omission that is worth taking note of - there is no 320x240 50Hz mode. I don't know why this is, because it's certainly not too difficult to do - it was just never included in KOS. If anyone really needs it, there is a patch to add that mode (DM_320x240_PAL) to KOS 1.2.0, and it should be included in KOS 1.2.1</p> <p>pixel_mode can be one of:</p> <table cols="4" rows="11" border="1"> <tr> <td>pixel_mode</td><td>Pixel size</td><td>Colour format</td> </tr> <tr> <td>PM_RGB555</td><td>15 bit</td><td>0RRRRRGGGGGBBBBB</td> </tr> <tr> <td>PM_RGB565</td><td>16 bit</td><td>RRRRRGGGGGGBBBBB</td> </tr> <tr> <td>PM_RGB888</td><td>24 bit</td><td>RRRRRRRR GGGGGGGG BBBBBBBB</td> </tr> </table> <p>The best mode to use on the Dreamcast is RGB565 - it provides fairly good colour quality, it's significantly faster than 24-bit mode, and it uses less memory. Just trust me on this - it's the best mode to use for pretty much everything that we're going to be doing.</p> <p>So, to initialise the screen to 640x480 60Hz, in RGB565 colour mode, we'd use the following line:</p> <pre>vid_set_mode(DM_640x480, PM_RGB565);</pre> <h2>RGB565 colour mode</h2> <p>In RGB565 mode, the three colour components are packed into two bytes. The upper 5 bits contain the red data, the next 6 contain the green data, and the last 5 contain the blue data. Red and blue range from 0 to 31, and green ranges from 0 to 63. The reason that green is given more space is because the human eye is more sensitive to green.</p> <p>Colours on a computer are typically represented using three bytes - one each for red, green and blue, ranging from 0 to 255. There's an easy way to convert from this format to the 16-bit RGB565 format that we need - we just use a macro:</p> <pre>#define PACK_PIXEL(r, g, b) ( ((r &amp; 0xF8) &lt;&lt; 8) | ((g &amp; 0xFC) &lt;&lt; 3) | (b &gt;&gt; 3) )</pre> <p>That macro uses two AND operations to mask out the unnecessary bits of the red and green components, bit shifts the values to get them into the correct place, and ORs them together. For some strange reason, that macro isn't included anywhere in KOS.</p> <h2>Drawing a single pixel</h2> <p>No matter how complex the graphics we're trying to make, no matter how many complex formulae and techniques we're using, no matter how long it's taken to draw our artwork, ALL 2D graphics come down to this - drawing a single pixel. For many things, where we need to plot multiple pixels at once, we can modify this routime to make it faster, but it'll still just be a variation on this. So how exactly do we draw a single pixel?</p> <p>On the Dreamcast, the image currently being displayed on the screen is stored in an area of video memory called the framebuffer. The pixels are stored in order, from left to right, then from top to bottom, each as a single 16-bit value. So in order to find the location in the framebuffer of a single pixel, we can use this formula:</p> <pre>location = x_coordinate + (y_coordinate * width)</pre> <p>So, assuming a resolution of 640x480, we can do this:</p> <pre>location = x + (y * 640)</pre> <p>Now all we need to know is where the framebuffer is. KOS provides us with a pointer to this location, named vram_s. So all we need to do the get the location in memory of a single pixel on the screen is:</p> <pre>vram_s[x + (y * 640)]</pre> <p>From there, it should be easy to see how to draw a single pixel - we just need to set the value of that location in memory to the colour we want the pixel to be:</p> <pre>vram_s[x + (y * 640)] = PACK_PIXEL(r, g, b);</pre> <h2>Clipping</h2> <p>Now that all works fine, until we come across one additional problem - clipping. What happens if we were to try to write to negative X or Y coordinates, or write off the bottom or the right of the screen? We'd be writing either to the wrong part of the screen, or an area of memory that we aren't allowed to write to. We could cause all kinds of problems. So we just don't do it - we have to add some checking to make sure we aren't trying to draw outside the screen:</p> <pre>if((x &gt;= 0) &amp;&amp; (x &lt; 640) &amp;&amp; (y &gt;= 0) &amp;&amp; (y &lt; 480)) vram_s[x + (y * 640)] = PACK_PIXEL(r, g, b);</pre> <p>Now we have a safe, effective way to draw a single pixel on the screen. Of course, it'd be more convenient as a macro:</p> <pre>#define DRAW_PIXEL(x, y, c) \ if((x &gt;= 0) &amp;&amp; (x &lt; 640) &amp;&amp; (y &gt;= 0) &amp;&amp; (y &lt; 480)) \ vram_s[x + (y * 640)] = c;</pre> <p>Now, to draw a single pixel, we can just work out the colour we want to set it to using PACK_PIXEL, and the use DRAW_PIXEL to draw it.</p> <h2>Example</h2> <p>The example program for this tutorial ([http://files.frashii.com/~sp00nz/Doom/files/BlackAura/tutes/2dgfx/example3.zip example1.zip]), draws pixels randomly to the screen, using PACK_PIXEL and DRAW_PIXEL. See if you can make it do something more interesting.</p> <h1>Horizontal and vertical lines</h1> <h2>Horizontal lines</h2> <p>Drawing pixels is probably getting kinda boring by now, so let's draw something more interesting. As a start, we'll draw a simple horizontal line, which is about the simplest shape you can do. A line is basically a load of pixels, arranged in a line. So they shouldn't be that hard to draw - we just need to draw a load of pixels in a line:</p> <pre>void draw_hline(int x1, int x2, int y, uint16 c) { int cx; // Draw the line for(cx = x1; cx &lt;= x2; cx++) DRAW_PIXEL(cx, y, c); }</pre> <p>One problem there - what if x2 is smaller than x1? The line won't be drawn. So, if x2 is smaller than x1, we should swap them around:</p> <pre>void draw_hline(int x1, int x2, int y, uint16 c) { int cx; // Swap x1 and x2 if necessary if(x1 &gt; x2) { cx = x1; x1 = x2; x2 = cx; } // Draw the line for(cx = x1; cx &lt;= x2; cx++) DRAW_PIXEL(cx, y, c); }</pre> <p>And that's it... Or is it? The more observant of you may notice that this code is actually very bloated. Remember that DRAW_PIXEL is checking if the pixel is on the screen for every pixel we draw. But, since this is just a horizontal line, we know that if both points are on the screen, the whole line is on the screen. If the line's off the screen entirely, we can just ignore it. If the line is on the screen, we can tell how much of the line is on the screen, and adjust the left and right coordinates appropriately. This is more or less the same thing as the clipping that DRAW_PIXEL does, but we only need to do it for the line, not each pixel:</p> <pre>void draw_hline(int x1, int x2, int y, uint16 c) { int cx; // Swap x1 and x2 if necessary if(x1 &gt; x2) { cx = x1; x1 = x2; x2 = cx; } // Don't bother if the line's off the screen if( (y &lt; 0) || (y &gt; 479) || (x1 &gt; 639) || (x2 &lt; 0) ) return; // Clip the line to the edge of the screen if(x1 &lt; 0) x1 = 0; if(x2 &gt; 639) x2 = 639; // Draw the line for(cx = x1; cx &lt;= x2; cx++) vram_s[cx + (y*640)] = c; }</pre> <p>That's a bit better, but there's still one problem - for each pixel, we're doing y*640, which will be the same for each and every pixel. In face, since we're drawing from left to right, each pixel will be next to the previous pixel. So we can do something like this:</p> <pre>void draw_hline(int x1, int x2, int y, uint16 c) { int cx; uint16 *line_buffer; // Swap x1 and x2 if necessary if(x1 &gt; x2) { cx = x1; x1 = x2; x2 = cx; } // Don't bother if the line's off the screen if( (y &lt; 0) || (y &gt; 479) || (x1 &gt; 639) || (x2 &lt; 0) ) return; // Clip the line to the edge of the screen if(x1 &lt; 0) x1 = 0; if(x2 &gt; 639) x2 = 639; // Set line_buffer to the beginning of the line line_buffer = vram_s + x1 + (y * 640); // Draw the line for(cx = x1; cx &lt;= x2; cx++) *line_buffer++ = c; }</pre> <p>That probably won't make a lot of sense unless you know something about pointers in C - line_buffer is set to the location of the first pixel of the line we're drawing. We then draw the pixel, and increment line_buffer by one pixel, so it now points to the location of the next pixel.</p> <p>A horizontal line is actually far more useful than it would first appear. A horizontal line is very useful for drawing filled shapes - you just draw a horizontal line from the left-most point of the shape on a given line, to the right-most point of the shape. Then you repeat that for each line. That's how most software rendered 3D games fill polygons.</p> <h2>Vertical lines</h2> <p>These are pretty much exactly the same as horizontal lines. However, we're now drawing down instead of right. Basically, we swap the X and Y coordinates around, and we skip 640 pixels instead of 1 - we jump down one pixel instead of right one pixel:</p> <pre>void draw_vline(int x, int y1, int y2, uint16 c) { int cy; uint16 *line_buffer; // Swap y1 and y2 if necessary if(y1 &gt; y2) { cy = y1; y1 = y2; y2 = cy; } // Don't bother if the line's off the screen if( (x &lt; 0) || (x &gt; 639) || (y1 &gt; 479) || (y2 &lt; 0) ) return; // Clip the line to the edge of the screen if(y1 &lt; 0) y1 = 0; if(y2 &gt; 479) y2 = 479; // Set line_buffer to the beginning of the line line_buffer = vram_s + x + (y1 * 640); // Draw the line for(cy = y1; cy &lt;= y2; cy++) { *line_buffer = c; line_buffer += 640; } }</pre> <p>If you can just adapt something you already have to perform a new function, it's usually a good idea to try it. Trivial modifications to code that you know works are usually easier to get working than writing the whole thing from scratch.</p> <h2>Hollow boxes</h2> <p>Now that we have the code to draw horizontal and vertical lines, drawing a hollow box should be very easy - we just draw two horizontal lines, and two vertical lines:</p> <pre>void draw_hbox(int x1, int y1, int x2, int y2, uint16 c) { draw_hline(x1, x2, y1, c); draw_hline(x1, x2, y2, c); draw_vline(x1, y1, y2, c); draw_vline(x2, y1, y2, c); }</pre> <h2>Filled boxes</h2> <p>All we do here is draw a series of horizontal lines, which will fill an area of the screen. We know what the left and right coordinates of the box are on each scanline, and we know how far up and down the box goes. So we can just do:</p> <pre>void draw_fbox(int x1, int y1, int x2, int y2, uint16 c) { int cy; for(cy = y1; cy &lt;= y2; cy++) draw_hline(x1, x2, cy, c); }</pre> <h2>Example</h2> <p>The example program for this tutorial ([http://files.frashii.com/~sp00nz/Doom/files/BlackAura/tutes/2dgfx/example2.zip example2.zip]), draws coloured gradients using the draw_hline and draw_vline functions, then draws a pattern using the filled and unfilled box functions. The video code is contained in a separate file which you can use in your own programs. Just copy video.c and video.h, put them into your own program, and #include video.h when you want to use the video functions. All future examples will be set up this way.</p> <h1>General lines</h1> <h2>Lines in any direction</h2> <p>So far, we've just drawn horizontal and vertical lines. They were easy, but they're also quite boring. So now we're going to draw lines that can go in any direction we want. Assuming you know some farily basic line geometry, drawing a line is pretty easy. However, the simple way is also very slow, which is where things start to get interesting.</p> <p>There are a multitude of ways to draw lines, ranging from the obvious to the utterly insane. The method I'm describing here is the most common, which was developed by Jack Bressenham at IBM. It's not the best, but it's comprehensible at least, and can be fairly easily derived.</p> <p>This kinda assumes that you know some basic line geometry, such as how to find the gradient (slope) of a line, and some other simple things (such as what the gradient actually is, and what you can do with it). I did this kind of stuff at school when I was about twelve or thirteen. If you didn't learn any of this, can't remember it, or fell asleep in class, you're going to find this a little difficult. That's what you get for not paying attention in math class.</p> <h2>Line geometry</h2> <p>In order to draw a line, we must first be able to define a line. Once we can develop a mathematical model of a line, we can try to tell a computer how to draw one.</p> <p>In general, and line can be defined by two values - it's gradient, and it's y-intercept. The gradient tells us how steep the line is, and the y-intercept tells us where the line intersects with the Y axis. In practical terms, we also need two end points, which simply define the limits of the line in the X axis. The Y coordinates of each end point can be calculated using the Y-intercept and the gradient, and therefore the gradient and Y-intercept can be calculated from the end points.</p> <p>The general equation for a line is...</p> <pre>y = mx + b</pre> <p>...where "x" and "y" are the coordinates of each point on the line, m is the gradient, and b is the y-intercept. Therefore, if we know the X coordinate of a point, we can find it's Y coordinate by plugging it into the above formula. We can use this to find the Y coordinate of any point between our two end points.</p> <p>Finally, we need to know how to calculate the Y intercept and gradient, assuming that we know the coordinates of two points on the line - the end points in our case. First, we calculate the gradient by dividing the Y displacement (Y2 - Y1) by the X displacement (X2 - X1). We can then use a slightly modified version of the first equation to find the y-intercept.</p> <h2>A first attempt</h2> <p>Now, that sounds easy (yeah, right), so let's put it into practice...</p> <pre>void draw_line(int x1, int y1, int x2, int y2, uint16 c) { float m, b; int dx = x2 - x1; int dy = y2 - y1; // Calculate gradient and y-intercept m = (float)dy / (float)dx; b = y1 - m*x1; // Work out which way we're going - left or right dx = (x2 &gt; x1) ? 1 : -1; // Draw start pixel DRAW_PIXEL(x1, y1, c); // Draw the line while (x1 != x2) { x1 += dx; y1 = (int)(m*x1+b); DRAW_PIXEL(x1, y1, c); } }</pre> <p>There's just one problem with that. If you try to draw some lines with it, you'll notice that it doesn't work for steep lines. We're moving from left to right, and plotting one pixel at the appropriate height. But, for steep lines, we'll just get a load of dots.</p> <h2>A working attempt</h2> <p>So how do we fix it? It works fine for any lines which are shallow, so we can keep that. All we have to do for steep lines is reverse the X and Y coordinates - we flip all X and Ys in the equations above, and move from top to bottom, calculate an X coordinate, and plot one pixel</p> <pre>void draw_line(int x1, int y1, int x2, int y2, uint16 c) { float m, b; int dx = x2 - x1; int dy = y2 - y1; // Draw start pixel DRAW_PIXEL(x1, y1, c); if(abs(dx) &gt; abs(dy)) { // Shallow lines m = (float)dy / (float)dx; b = y1 - m*x1; dx = (x2 &gt; x1) ? 1 : -1; while (x1 != x2) { x1 += dx; y1 = (int)(m*x1+b); DRAW_PIXEL(x1, y1, c); } } else { // Steep lines m = (float)dx / (float)dy; b = x1 - m*y1; dy = (dy &lt; 0) ? -1 : 1; while(y1 != y2) { y1 += dy; x1 = (int)(m*y1+b); DRAW_PIXEL(x1, y1, c); } } }</pre> <h2>Digital differential analyser</h2> <p>Remember I said that this method was slow? Can you see why? When it calculates the X or Y coordinates for each point, it must multiply two numbers together. Since multiplications are quite slow, this slows the whole thing down. We can get around this by using additions instead.</p> <p>Every time we do a multiplication, we're multiplying the gradient by the next Y or X coordinate. The gradient is always constant, and the X or Y coordinates are always exactly one more or one less than they were before. That means that, instead of the multiplication, we can just add or subtract the gradient each time.</p> <p>This technique is an example of a digital differential analyzer, apparently. I have no idea what a DDA actually is, but I know that this is one. The same idea applies to some other things, but nothing that's immediately relevant. So you may as well forget about it.</p> <pre>void draw_line(int x1, int y1, int x2, int y2, uint16 c) { float m; int dx = x2 - x1; int dy = y2 - y1; float t = 0.5; // Draw start pixel DRAW_PIXEL(x1, y1, c); // Shallow lines if(abs(dx) &gt; abs(dy)) { // Shallow lines m = (float)dy / (float)dx; t += y1; dx = (x2 &gt; x1) ? 1 : -1; m *= dx; while (x1 != x2) { x1 += dx; t += m; DRAW_PIXEL(x1, t, c); } } else { // Steep lines m = (float)dx / (float)dy; t += x1; dy = (dy &lt; 0) ? -1 : 1; m *= dy; while(y1 != y2) { y1 += dy; t += m; DRAW_PIXEL(t, y1, c); } } }</pre> <h2>Bresenham's algorithm</h2> <p>This is a refinement of the DDA line algorithm above. To be totally honest, I don't know if this is any faster on the Dreamcast, because it makes some assumptions that aren't necessarily true on the SH-4. Specifically, it assumes that floating point operations are slower than integer operations, and that you can't compare two arbitrary numbers - you can only compare one number to zero. I don't see how it could be any slower, so we might as well give it a try. If anyone can be bothered to benchmark these, tell me what results you get.</p> <p>Anyway, all this does is removes all floating point operations in favour on integer operations, makes all comparisons relative to zero, and removes the division used to calculate the gradient.</p> <pre>void draw_line(int x1, int y1, int x2, int y2, uint16 c) { int dy = y2 - y1; int dx = x2 - x1; int stepx, stepy; if (dy &lt; 0) { dy = -dy; stepy = -1; } else { stepy = 1; } if (dx &lt; 0) { dx = -dx; stepx = -1; } else { stepx = 1; } dy &lt;&lt;= 1; dx &lt;&lt;= 1; DRAW_PIXEL(x1, y1, c); if (dx &gt; dy) { // Shallow lines int fraction = dy - (dx &gt;&gt; 1); while (x1 != x2) { if (fraction &gt;= 0) { y1 += stepy; fraction -= dx; } x1 += stepx; fraction += dy; DRAW_PIXEL(x1, y1, c); } } else { // Steep lines int fraction = dx - (dy &gt;&gt; 1); while (y1 != y2) { if (fraction &gt;= 0) { x1 += stepx; fraction -= dy; } y1 += stepy; fraction += dx; DRAW_PIXEL(x1, y1, c); } } }</pre> <h2>Making it faster</h2> <p>There's one final thing we can do to make the line drawing function work faster. It still uses DRAW_PIXEL, which means we're going clipping tests and a multiplication for each pixel.</p> <p>Removing the multiplications is actually quite easy. We keep a pointer to the pixel currently being drawn, and move that pointer around as we need to. The problem is that we can now draw lines outside the screen, which can cause all sorts of problems, along with graphical corruption. That means we'd have to add some clipping routines. There are about as many ways to clip a line as there are to draw a line, and they're all a complete pain in the backside to explain or implement. So I'm not going to go through them now. Maybe later.</p> <p>If you need more speed, you can use a totally different line drawing algorithm, such as Xiaolin Wu's 2-step algorithm, which is a rather novel approach to drawing lines. If you want to know more about how any of this stuff works, here's some sites you should look at:</p> <ul> <li> [http://graphics.lcs.mit.edu/%7Emcmillan/comp136/Lecture6/Lines.html">Line-Drawing Algorithms] </li> </ul> <h2>Example</h2> <p>The example program for this tutorial ([http://files.frashii.com/~sp00nz/Doom/files/BlackAura/tutes/2dgfx/example3.zip example3.zip], uses the line function we just developed to draw patterns on the screen. It draws two arch shapes, and a weird spirograph-like shape in the middle of the screen.</p> 22865bbb8ebd9921eadfb0e2f7d9f1b8686492e4 PowerVR Introduction 0 960 2138 2023-03-02T01:06:50Z Unknown user 0 Created page with "==Introduction by BlackAura== This tutorial was written by [[BlueCrab]] and [[BlackAura]]. It covers using the PowerVR hardware of the Dreamcast to do pretty much the same th..." wikitext text/x-wiki ==Introduction by BlackAura== This tutorial was written by [[BlueCrab]] and [[BlackAura]]. It covers using the PowerVR hardware of the Dreamcast to do pretty much the same thing as my first four 2D graphics tutorials, so it might be a good idea to have a look at those first - much of it, especially in the first part about Dreamcast video modes, still applies when using the PowerVR hardware. I also added a couple of comments to clarify the usage of some of the code. Those notes are written in italics. Anyway, over to BlueCrab... ==Initialization== Just a few little differences between regular, and PVR init. First of all, set your video mode, like BlackAura stated above. Immediately after this, you need to initialize the PVR, if you'd like to use it. This can be done most simply like this: pvr_init_defaults(); This will set up the PVR with reasonable defaults for all settings. I've never had to muck around with the settings, and I find the defaults to be pretty good. ==Scene drawing== When using the PVR, one needs to tell it when beginning a new scene, and what polygon lists will be used. This is done as follows. (You also must close everything when you're done with it!) ''The Dreamcast uses display lists when it's drawing the screen, and it expects all the opaque drawing instructions to be in one part of the list, followed by all the transparent parts. So if something's going to be transparent, make sure you draw it into the transparent display list!'' pvr_scene_begin(); pvr_list_begin(PVR_LIST_OP_POLY); // Do opaque drawing here! pvr_list_finish(); pvr_list_begin(PVR_LIST_TR_POLY); // Do Translucent drawing here pvr_list_finish(); pvr_scene_finish(); ==Horizontal lines== Horizontal lines are fun, aren't they! Anyway, here's a method I use to draw horizontal lines of any color on the screen. void hline_tr(float x1, float x2, float y, uint8 a, uint8 r, uint8 g, uint8 b) { pvr_poly_hdr_t hdr; pvr_poly_cxt_t cxt; pvr_vertex_t vert; float cx; if(x1 > x2) { cx = x1; x1 = x2; x2 = cx; } pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); pvr_poly_compile(&hdr, &cxt); pvr_prim(&hdr, sizeof(hdr)); vert.flags = PVR_CMD_VERTEX; vert.x = x1; vert.y = y + 1; vert.z = 5.0f; vert.u = 0; vert.v = 0; vert.argb = PVR_PACK_COLOR(a / 255, r / 255, g / 255, b / 255); vert.oargb = 0; pvr_prim(&vert, sizeof(vert)); vert.y = y; pvr_prim(&vert, sizeof(vert)); vert.x = x2; vert.y = y + 1; pvr_prim(&vert, sizeof(vert)); vert.flags = PVR_CMD_VERTEX_EOL; vert.y = y; pvr_prim(&vert, sizeof(vert)); } ''Since these lines can be transparent, you have to draw lines into the transparent display list. If you try to draw it into the opaque list, nothing will happen.'' ==Vertical lines== Once again, the wonderful vertical line. Here's my method of drawing vertical lines: void vline_tr(float x, float y1, float y2, uint8 a, uint8 r, uint8 g, uint8 b) { pvr_poly_hdr_t hdr; pvr_poly_cxt_t cxt; pvr_vertex_t vert; float cy; if(y1 > y2) { cy = y1; y1 = y2; y2 = cy; } pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); pvr_poly_compile(&hdr, &cxt); pvr_prim(&hdr, sizeof(hdr)); vert.flags = PVR_CMD_VERTEX; vert.x = x /* - 1 */; vert.y = y2; vert.z = 5.0f; vert.u = 0; vert.v = 0; vert.argb = PVR_PACK_COLOR(a / 255, r / 255, g / 255, b / 255); vert.oargb = 0; pvr_prim(&vert, sizeof(vert)); vert.y = y1; pvr_prim(&vert, sizeof(vert)); vert.x = x + 1; vert.y = y2; pvr_prim(&vert, sizeof(vert)); vert.flags = PVR_CMD_VERTEX_EOL; vert.y = y1; pvr_prim(&vert, sizeof(vert)); } ==Triangles== Just a short note about triangles. All verteces need to be submitted clockwise. The same goes for the diagonal line function later. These functions have no protection for if someone submits them in the wrong order, and most likely, there will be no triangle on the screen if you do. void arrow(float x1, float y1, float x2, float y2, float x3, float y3, uint8 a, uint8 r, uint8 g, uint8 b) { pvr_poly_hdr_t hdr; pvr_poly_cxt_t cxt; pvr_vertex_t vert; pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); pvr_poly_compile(&hdr, &cxt); pvr_prim(&hdr, sizeof(hdr)); vert.flags = PVR_CMD_VERTEX; vert.x = x1; vert.y = y1; vert.z = 5.0f; vert.u = 0; vert.v = 0; vert.argb = PVR_PACK_COLOR(a / 255, r / 255, g / 255, b / 255); vert.oargb = 0; pvr_prim(&vert, sizeof(vert)); vert.x = x2; vert.y = y2; pvr_prim(&vert, sizeof(vert)); vert.flags = PVR_CMD_VERTEX_EOL; vert.x = x3; vert.y = y3; pvr_prim(&vert, sizeof(vert)); } ==Diagonal lines== The last thing I'll be covering, at least today, is diagonal lines. Remember Coordinates must be put in in a certain order. (see note below code) void line_tr(float x1, float y1, float x2, float y2, uint8 a, uint8 r, uint8 g, uint8 b) { pvr_poly_hdr_t hdr; pvr_poly_cxt_t cxt; pvr_vertex_t vert; pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); pvr_poly_compile(&hdr, &cxt); pvr_prim(&hdr, sizeof(hdr)); vert.flags = PVR_CMD_VERTEX; vert.x = x1; vert.y = y1; vert.z = 5.0f; vert.u = 0; vert.v = 0; vert.argb = PVR_PACK_COLOR(a / 255, r / 255, g / 255, b / 255); vert.oargb = 0; pvr_prim(&vert, sizeof(vert)); vert.x = x2; vert.y = y2; pvr_prim(&vert, sizeof(vert)); vert.x = x1 + 1; vert.y = y1; pvr_prim(&vert, sizeof(vert)); vert.flags = PVR_CMD_VERTEX_EOL; vert.x = x2 + 1; vert.y = y2; pvr_prim(&vert, sizeof(vert)); } This diagonal line code should be able to handle any kind of line, I just use the horizontal and vertical line routines above. Anyway, here's the note I mentioned above: line_tr(32, 48, 48, 32, 255, 255, 255, 255); Will draw a line like tihs slash: / that is white, and completely opaque. line_tr(48, 288, 32, 272, 255, 255, 255, 255); Will draw a completely opaque, white line that looks similar to this slash: \ That's all for today, let me know if you see any improvements, or problems with this tutorial lesson. fe4696408321c3e53bbd3d3539b9fd9ec856cf0d File:Cyg01.jpg 6 961 2139 2023-03-02T01:08:02Z Unknown user 0 wikitext text/x-wiki Cyg01 05a8eea8b577c157d63a0f0abd5bd56909763013 File:Cyg02.jpg 6 962 2140 2023-03-02T01:08:12Z Unknown user 0 wikitext text/x-wiki Cyg02 ddab157a2685fb78b8873430a213a127cad2f44b DreamSpec 0 964 2144 2023-03-02T01:28:15Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DreamSpec| image=N/A| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=1.0| downloads=[http://www.dcemulation.org/d..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSpec| image=N/A| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=1.0| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/Dspecv1-sound.zip Plain Files]| release date=Unknown| author=BigBoy| original=N/A | systems=Spectrum| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: BigBoy Version: 1.0 Last Updated: 6-11-02 Description: The Best Spectrum emulator on the Dreamcast! Status: Now has SOUND and supports spectrum BRIGHT mode Supports RGB and VGA, as well as Loading and Saving to VMS! =Downloads= '''All files are non-Selfbooting''' * 1.0 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/Dspecv1-sound.zip Plain Files] - 261kb No games included. * 0.0005 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreamspecCDIv0.5.zip Disk Juggler] 7.22mb 200 Games Inlcuded =Old Versions= * 0.0003 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/DreamSpec3Files.zip Plain Files] 200kb No games included. [[Category:Emulator]] 6d13176f6ce250a25ebffd8439739085ba9ff963 Dream MSX 0 965 2145 2023-03-02T01:29:36Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=DreamMSX!| image=N/A| homepage=Unknown| version=0.2g| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreammsxMA..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamMSX!| image=N/A| homepage=Unknown| version=0.2g| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreammsxMAE.zip Plain Files]| release date=Unknown| author=Joe Kwanten| original=N/A | systems=MSX| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Jos Kwanten Version: 0.2g Last Updated: 09-18-01 Description: An MSX emulator for your dreamcast. This is one of the greatest ports ever. It comes with full sound and music and its running at FULL SPEED. This release comes with metal gear and paradus built in. <br/> Status: There is sound and runs at full speed. =Downloads= * [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreammsxMAE.zip Plain Files] Self-Boot:No ZIP 494Kb =Old Version= [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/dreammsx02f.zip Plain Files] Self-Boot:No ZIP 265Kb 2 Games included. [[Category:Emulator]] 818f14f5bf28c4530712660d225f749b916e892f FMSX DC 0 966 2146 2023-03-02T01:30:36Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=fMSX DC| image=N/A| homepage=Unknown| version=Beta 1| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/fmsxdc-scr..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=fMSX DC| image=N/A| homepage=Unknown| version=Beta 1| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/fmsxdc-scrm.zip Plain Files(Selbooting)]| release date=Unknown| author=Arnon Cardoso| original=fMSX| systems=MSX| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Arnon Cardoso Version: Beta 1 Last Updated: February 19, 2002 Description: A port of the MSX emulator fMSX Status: *Used Stored Queues to improve performance. *Changed Z80 engine to not use a big switch but the result was disappointing. *MSX Joystick support. If you have two DC joysticks the first will act as of DreamMSX and the second can be used as MSX Joy A or B (selectable using the GUI). *GameMaster II SRAM save to VMU, using NesterDC VMU code. *Better GUI (?) than DreamMSX. Besides the options offered by DreamMSX you can also: ** - select MSX version up to 2+ (2+ emulation is partial though). ** - Synchronize the video updates to a frequency (50 or 60). *FM sound. *Disk swap after the emulation has started. *MSX 2+ screen modes. *256 files limit to roms and disks (each one). '''Make sure you have the controllers and vmu connected when booting fMSX for DC.''' =Downloads= * Beta 1 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/fmsxdc-scrm.zip Plain Files(Selbooting)] 147kb [[category:emulator]] 882e26d9e0b82defb2e6c6ee7b6951b1343a62cd Spectrum 128k 0 967 2147 2023-03-02T01:31:09Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=Spectrum 128k!| image=N/A| homepage=[http://imrtechnology.ngemu.com/ Homepage]| version=v1| downloads=[http://www.dcemulation.org/fil..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=Spectrum 128k!| image=N/A| homepage=[http://imrtechnology.ngemu.com/ Homepage]| version=v1| downloads=[http://www.dcemulation.org/files/emulators/spec128ktv.rar Plain Files(Scrambled)]| release date=Unknown| author=Ian Micheal| original=N/A | systems=Sinclair Spectrum| best=No| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ian Micheal Updated: 16-02-04 Description: A Speccy128k emu. =Downloads= * v1 - [http://www.dcemulation.org/files/emulators/spec128ktv.rar Plain Files(Scrambled)] 790kb [[Category:emulator]] 7f7f12b635c3bc023547ee376f6356550959f0cd Ghetto Pong 0 968 2148 2023-03-02T01:34:26Z Unknown user 0 Created page with "Ghetto Pong is a pong clone by Jordan DeLong and [[Dan Potter]]. http://www.dcemulation.com/dl/dl.php3?url=files/software/ghetto_pong_10final_binary.tar.gz" wikitext text/x-wiki Ghetto Pong is a pong clone by Jordan DeLong and [[Dan Potter]]. http://www.dcemulation.com/dl/dl.php3?url=files/software/ghetto_pong_10final_binary.tar.gz c397bb846883ca1ac874cf983f3f41ba03d3797f Maturion 0 969 2149 2023-03-02T01:35:01Z Unknown user 0 Created page with "Maturion is a German Dreamcast fan and he is running [http://www.sega-dc.de SEGA-DC.DE (DC-Germany)]. He also ported Pocket Volleyball to the Dreamcast and called it Pocket..." wikitext text/x-wiki Maturion is a German Dreamcast fan and he is running [http://www.sega-dc.de SEGA-DC.DE (DC-Germany)]. He also ported Pocket Volleyball to the Dreamcast and called it [[Pocket Volleyball DC]]. ==Weblinks== *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=29699 Maturion's profile on DCEmulation] *[http://www.sega-dc.de SEGA-DC.DE] *[http://www.maturion.de Maturion.de] e8d73fe0c8716282f73b09912378ca9a1de09fd0 Gonzo 0 970 2150 2023-03-02T01:35:24Z Unknown user 0 Created page with "Gonzo was a Dreamcast programmer from Austria. He released [[(D)Colem]] and [[odd-DC]]. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=6867 Gonzo's profile..." wikitext text/x-wiki Gonzo was a Dreamcast programmer from Austria. He released [[(D)Colem]] and [[odd-DC]]. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=6867 Gonzo's profile on DCEmulation] 6ce7405388243632595825172e3527c3f8e4968b Adrian O'Grady 0 955 2151 2127 2023-03-02T01:36:08Z Unknown user 0 wikitext text/x-wiki Adrian O'Grady was an active contributor to the [[LinuxDC]] project. He was also involved in the GBA scene. His blog, fivemouse.com, disappeared in 2006, after 4 years without any update. ''This interview with [[Adrian O'Grady]] was taken by Wraggster in 2002 for ConsoleVision.com.'' '''Consolevision: Tell us about yourself. Where were you born, where do you live... ?''' Adrian: Well, I was born in and brought up in Hayes (near Heathrow) and I now live in Hatfield while I'm attending university here. With any luck, I should graduate in June and be moving on to somewhere much nicer. :-) '''Consolevision: What qualifications do you have?''' Adrian: Just A-Levels now, but Hopefully, I should have a BSc Computing and Networks degree within a few months. So anyone who has a job available... '''Consolevision: What made you get into computers?''' Adrian: I'm not sure I can say what exactly as I've always had computers around me. I know my brother got his first computer before I could remember (it may have even been before I was born), it was a kit I believe. The first computer I remember using was an Atari 800 which my Dad bought. '''Consolevision: What made you get into programming? What was your first program?''' Adrian: 10 PRINT "ADRIAN" 20 GOTO 10 I think I was about 4 years old at the time. I seriously got into programming though when I was about 12 or 13 though. I used to type up a lot of the programs from books like 1001 BASIC programs and change them for my friends. I did write a snail race program once though. '''Consolevision: What got you interested in GBA coding in the first place?''' Adrian: I'm not sure really. I think because it was more of a challenge than programming for a PC or DC. Certainly the idea of a web server in the palm of my hand was part of the motivation. It very nearly didn't happen though. My original idea for my final year project was a word processor for the Dreamcast. I wanted to write something that was technically perfect but practically useless so that the university couldn't make any money out of my project. '''Consolevision: Your GBA Web Server project is a great idea, how close are we to seeing the fruits of your labour?''' Adrian: Very. Very, very! :-) I'm currently writing up my final report. The reason the web site has been quiet is because I've been busy on the report and other university coursework. Fortunately, I'm able to give you a date. Thursday, the 18th of April. This is the date that my project must be handed in, therefore my web server has to be finished by then. I can't say when it'll be hosted though, but you'll at least be able to download a working version with all the tools required to try it out for yourself. '''Consolevision: Is the project everything you hoped it to be?''' Adrian: There are a couple of ambitious features I originally aimed to have but have been dropped. As it turns out, they just weren't required and so functionally, it remains the same. When I'm holding the web server in my hands when it goes live for the first time, I'll know that I've achieved everything I set out to do. '''Consolevision: After the initial release of GBA Web Server, what features are you hoping to add further down the line? Adrian: A simple scripting engine. This would allow you to hook the GBA up to any PPP server, such as the Windows one, or even an external modem! '''Consolevision: On the Dreamcast side, did you get anywhere with your work on [[LinuxDC]], if so can anything be added to what could be a significant piece of software for the dreamcast?''' Adrian: DC Linux is a bit of a sore point at the moment. :-) I did recompile a new version of the kernel with PPP support and a few other bits, but I broke my coders cable. And I blew up two of my Dreamcasts. They're currently sitting in a box waiting to be repaired but I've been told that'll have to wait 13 weeks for the parts I require. I think there has been a lot of confusion as to my input into DC Linux. Most people who email me think that I've actually ported it myself or have been part of the team. This is not the case at all. All I was doing was creating CD images that people without Linux or Cygwin could use. I was also just cross compiling applications for the SH4. Anyone else who was interested in it could easily carry on DC Linux. I simply haven't got the time or the resources. I can offer the web space and bandwidth though if someone was genuinely interested. '''Consolevision: Do have any projects in the works? Or would love to do?''' Adrian: I have had a couple of idea for what I will do after I finish the web server. They are mostly GBA related. However, I did start work on a version of BASIC for the Dreamcast but never had the time to put some real work into it. If I was to pick up work on that again, I'd like to do it as part of a collection of other application. I miss the days of a front room computer as opposed to a games console, you know, the Spectrum through to the Amiga. I feel that the Dreamcast could actually fill that gap. After all, when does a games console become a computer? I can do most things to a certain extent on my Dreamcast that I can on my PC. '''Consolevision: Apart from your own projects, has there been a homebrew game/project that you have played more than once? Or something that you can't wait to try?''' Adrian: Foon! I really, really love that emulator. It's been sitting on my flash cart now since the first version was released. '''Consolevision: What are you thoughts on the GBA homebrew scene, How do you think it could be improved?''' Adrian: I think the scene is coming along very nicely, much faster than I ever expected it to. One thing I would like to see more of though are the unique project you'd never think of doing. For example, one of the first homebrew projects I saw for the Gameboy was a control unit for small robot. Stuff like that, when people have looked at it and said to themselves, "This is more than just a games console..." really interests me. '''Consolevision: Whats your opinion on the current next gen consoles Dreamcast, Xbox, GameCube, Playstation 2?''' Adrian: Dreamcast: This is a great little box and I don't think people realised just how powerful it was. If it had a bit more memory and larger VMUs, you would have seen some truly amazing games. I'm really sad to see its commercial end as it's the console that I've probably enjoyed owning the most. If homebrew interest keeps building, I think the DC will have a long future in that area. PS2: Nice games, but it just doesn't excite me enough to buy one. If I were do to another console project, I'd rather do it on the Dreamcast to be honest. Xbox: I am really impressed with it but hate the way the general public is dismissing it. This I imagine is because of the price though. I'd love to get hold of a dev kit and start programming for it. I recon I could get a web server running on it in no time! :-) Someone I know has ported a spectrum emulator to it and I'd love to give that a go. It's just a shame that retail boxes are locked to stop running independent code. I guess that's the cost of piracy prevention. Gamecube: I will probably buy one sooner or later. I'm interested to give the GBA to GC link up a go. I'm sure there's a good project in there somewhere. As for a pure GC project though, again I'd have to say I'd just rather do it on the Dreamcast. '''Consolevision: And the mandatory question, what are your favorite games on every system you've owned?''' Adrian: *Atari 800: Miner 2049, Orc Attack, Centipede *Spectrum: Manic Miner, Trap Door, Ranarama *Amiga: Walker *Atari ST: Chaos (it's a PD conversion of a classic spectrum game) *PC: Far too many. *SNES: Super Mario World *Jaguar: Tempest *Saturn: Sega Rally, SWWS 98, Nights *N64: Mario Kart, 1080 *Dreamcast: Revolt, PSO, Alien Front Online, MSR *Xbox: Halo, Project Gotham, NHL 2002 *Gameboy: Alfred Chicken, Zelda *GBC: Tetris DX, Cannon Fodder, Zelda *GBA: Advance Wars, Chu Chu Rocker, Mario Kart, Doom 3065073ff6cb835fd8d2ea634c02df4b73ff6949 GPF 0 971 2152 2023-03-02T01:37:55Z Unknown user 0 Created page with "GPF is a Dreamcast developer. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=4702 GPF's profile on DCEmulation] *[http://gpf.dcemu.co.uk GPF's website] Th..." wikitext text/x-wiki GPF is a Dreamcast developer. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=4702 GPF's profile on DCEmulation] *[http://gpf.dcemu.co.uk GPF's website] This interview was taken by Maturion for an unreleased German SEGA magazine in November 2007. '''Maturion: Hi GPF. Thank you for your time. Do you have any (active) Dreamcast projects or are you only developing for other systems at the moment?''' GPF: I am currently just developing for the Nintendo DS, my monitor died that i used with my dev dreamcast and I haven't had a chance to replace yet I did some dreamcast dev about a month ago, did a port of dosbox 0.71 to the dreamcast based off the psp source diff's using the Chankast emulator and friends to test on hardware. '''Maturion: Ok, I see. Well, Why and when did you start with Dreamcast programming?''' GPF: Well i got my first dreamcast back in Christmas of 99, was seeing a lot of discussions of running homebrew so that was the main reason I got one i think. I started dreamcast coding in febuary/march 2000, originally having to burn multisession cdr's and bring it to the living room to test each build '''Maturion: What do you think about the future of the Dreamcast-Scene? Will the Dreamcast see some more homebrew projects or will the DC Scene die out soon after 2008? It's a very old machine...''' GPF: I don't think it will die out, there are still active projects/developers for even older hardware/consoles. Maybe fewer releases... '''Maturion: Will you ever start working on your Nintendo64-Emulator again and do you think any commercial games will be playable on it?''' GPF: probably not, it was originally done as a tech demo to show it was possible to run n64 code on a dreamcast Last year I was working on a new n64 emulator for the dc, working with pspmonkey as he was writing one for the psp I got the 2d part ported, but I don't have any 3d coding experience so I stopped working on it and I don't know sh4 asm, which would definetly be needed to do a dynarec/HLE type engine. '''Maturion: Do you have any plans on a new dreamcast project?''' GPF: Not currently, but I hope to get my dc dev setup working again and then see what the future holds '''Maturion: Let's ask our last question: Do you think SEGA will ever make a new console?''' GPF: I think they will surprise us with one someday '''Maturion: Thank you for your time!''' GPF: You are welcome. b082a8d80920e8cebe77656ff54c0d3ed908fb4f File:Vmiwriter.jpg 6 972 2153 2023-03-02T01:39:24Z Unknown user 0 wikitext text/x-wiki Vmiwriter 35d870b4514ec8f8d5ab0b0c213c8cf567c03c7b VMI Writer 0 973 2154 2023-03-02T01:39:33Z Unknown user 0 Created page with "{{Infobox_Tools_Information| name=VMI Writer| image=[[Image:Vmiwriter.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=1.0.5| downloads=[ht..." wikitext text/x-wiki {{Infobox_Tools_Information| name=VMI Writer| image=[[Image:Vmiwriter.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=1.0.5| downloads=[http://dchelp.dcemulation.org/?download=vmiwriter_105.zip Binary]<br />[http://dchelp.dcemulation.org/?download=vmiwriter_105_src.zip Source]| release date=4/14/2007| author=fackue| isactive=Yes }} This tool's purpose is creating [[VMI]] files for game saves that just have a [[VMS]]. It can also be used to edit and fix any VMIs with bad CRCs or incorrectly listed VMS file sizes. 925c430b59201a8f4d34fdda6f2e32a71fbeb434 Scherzo 0 812 2155 1957 2023-03-02T01:49:52Z Unknown user 0 wikitext text/x-wiki Scherzo was a Dreamcast prorgammer. He released [[Super Famicast]] and [[NesterDC SE]]. We have also [[Interviews:Scherzo|interviewed]] him. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=14018 Scherzo's profile on DCEmulation forums] *[http://www.sch3rz0.com Scherzo's Site] This interview with [[Scherzo]] was taken by [[Maturion]] on May 13, 2008. '''Do you have any (active) Dreamcast projects or are you focusing on other projects/systems?''' No, sorry to say that I don't have any side projects going on right now. The effort I give at work really drains my desire to program. I'm not ruling out coming back and doing something. If I did I would probably clean up some loose ends with NesterDC SE. I would also like to make a game completely from scratch. '''Why did you create NesterDC SE?''' There are many reasons I decided to improve upon NesterDC. First, there is so much stuff I love about the NES beyond the games; the music, the art, the gigantic cartridges themselves. And while I have a good collection of NES hardware I wanted to create a virtual museum of NES goodness. Second, there were compatibility issues with the last version of NesterDC and I saw it as a good challenge to fix them. I had never really worked on an emulator before and saw this as a chance to see how one functions. '''How long have you spent working on this project and what difficulties did you have?''' I'd say it took me a good year to put it all together. Lots of time was spent outside of coding, collecting and organizing the media of the various features of the project. Debugging the CPU core was tricky. To figure it out, I ended up building a windows version of Nester that used the DC optimized CPU code. I would run the modifed one along side an untouched NesterJ, with each of them logging the CPU state to files. I would then compared logs and try to pinpoint which combination of register values and opcodes that caused them to diverge. It was very rewarding to pull off. Another feature I'm particularly proud of is the stereo separation of the NES sound channels. I had heard this done in the NotSoFatso Winamp plugin and was amazed at how much cooler my favorite NES jams were. I didn't think that I was going to have enough free CPU to work with. But it all came together. '''How was feedback of the community to NesterDC SE?''' Aside from a few things that I simply did not have the energy or time to complete, I achieved everything I wanted, and people in the community really seemed to appreciate my work. There was other great work going on at the time. So I was rather surprised to win Favorite DC Emulator in 2006, especially since it was a derived work. '''Why and when did you start with Dreamcast programming?''' I first started coding for the Dreamcast because not enough was being done at the time in terms of SNES emulation. I wanted to see if I could have success optimizing Snes9x ported freshly to Dreamcast. It didn't go as well as I hoped and DreamSNES was still faster. But I tried. '''What do you think about the future of the Dreamcast-Scene and the Dreamcast-Scene now?''' The Dreamcast remains a very powerful system and capable of hosting just about anything that anyone can conjure in their imagination. I think there will always be a handful of developers actively working on Dreamcast related projects. They are just going to come and go. If people are still making things for NES and the Atari 2600, why not the DC? There's never been a video game console that makes it so easy to develop. '''Thank you for your time.''' Thanks. bb3c70d20f16a3d949e450c2bb7f4a6035c24eba VC/DC 0 974 2156 2023-03-02T01:50:49Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=VC/DC| homepage=[http://code.google.com/p/vcdc Homepage]| price=free| version=0.2| downloads=[http://code.google.com/p/vcdc/downloa..." wikitext text/x-wiki {{Infobox_Dev_Information| name=VC/DC| homepage=[http://code.google.com/p/vcdc Homepage]| price=free| version=0.2| downloads=[http://code.google.com/p/vcdc/downloads/list Offsite Link] | release date=6/6/2007| author=[[OneThirty8]]| isactive=Yes }} VC/DC is a basic VCD and MPEG stream player for Dreamcast developed by Josh Sutherland ([[OneThirty8]]). It is based on code from several open-source projects including libmpeg2/mpeg2dec, mpglib/mpg123, LAME, libID3, GhettoPlay, and vcdimager. Version 0.1a implemented a single circular buffer in the audio output system. This improved the viewing experience on some files while rendering others unwatchable due to the inefficient way in which the audio output was handled. Version 0.2 handles the audio and video output routines more efficiently, which minimizes the aforementioned problem from the 0.1a release, and most VCD-quality files should be watchable, and with fewer dropped frames. VC/DC 0.2 also is the first to support Playback Control, which most users will recognize as the ability to navigate VCD menus. Much time has been taken to ensure that the most commonly-used features will function as expected, although several features that the author felt were less important are either not working or untested. The player is in active development and further improvements in playback quality and features are expected. = Supported Formats = *((S)VCD (real discs or bin/cue files produced with the GNU VCDImager suite) *MPEG-1 and MPEG-2 program streams (*.mpg, *.mpeg) *MPEG-1 and MPEG-2 elementary video streams (*.m1v, *.m2v) *MPEG elementary audio streams (*.mp1, *.mp2, *.mp3) *Dreamcast Sofdec movies (*.sfd, untested and won't play audio) *Playstation2 pss movies (*.pss, barely tested and won't play audio) = Supported Features = *ID3 tags in MP3 files *Fast-Forward *Pause *Stop *Skip between VCD Entry Points on any VCD/SVCD authored with chapters *Playback Control and Extended Playback Control on VCD 2.0 and SVCD/HQVCD, with a few minor limitations. Most users will understand this as the ability to use menus on VideoCD, similar to a DVD menu. *Beginning with VC/DC 0.2, the application's main menu is themable with [[DCDivX]]-like themes. = Controls = == In the menu == * DPAD-UP/DOWN browses the menu. * Y adds the selected file to a playlist. * A plays a file/playlist or opens a folder. * X gives you a rather crappy-looking settings menu. * DPAD-LEFT/RIGHT change the settings in the settings menu. * START will replay a VCD. == In a movie == * A will pause/resume. * Y will stop and bring you back to the menu. * Analog right will fast-forward. == VCD-only controls == * D-Pad Right will skip to the next chapter (or the 'next' item defined in the current PSD item). * D-Pad Left will skip to the previous chapter (or the 'prev' item defined in the current PSD item). * B will display/hide a numerical entry box in the top right-hand corner of the screen, as well as a pointer (controlable with the analog stick) if there are hotspots in the current PBC item. * D-Pad Left/Right will increment/decrement the avobe-mentioned number by 1. * D-Pad Up/Down will increment/decrement the number by 10. * A will enter the chosen number and close the numerical selection box (or pause if that box is closed). * START acts as the 'Default' button on a VCD remote. * X acts as the 'Return' button on a VCD remote. 1e2ce66ea29ac7d39f87deb1c3e178ed2ef906e9 Template:Infobox Dev Information 10 975 2157 2023-03-02T01:51:19Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|<i>No Screenshot Available</i>}}} |- style="background:#ffffff" |Homepage || {{{homepage|<i>Unknown</i>}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|<i>Unknown</i>}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |} 041480beb9b6e2c541ef4ab5b8c8ee854d804f6c Quzar 0 976 2158 2023-03-02T01:52:18Z Unknown user 0 Created page with "'''Quzar''' is a programmer that was part of the development team [[Screamcast]]. ==Released projects== In 2004, he ported the DOS emulator [[bhole]] to the Dreamcast. In 200..." wikitext text/x-wiki '''Quzar''' is a programmer that was part of the development team [[Screamcast]]. ==Released projects== In 2004, he ported the DOS emulator [[bhole]] to the Dreamcast. In 2005, he ported the PC Engine emulator, [[HuCast]], to the Dreamcast. Also in 2005, he was part of the team that ported the Neo Geo emulator [[NeoDC]] to the Dreamcast. In 2006, he made the second port of [[Dodgin' Diamond 2]] to the Dreamcast, this time based on the PC version. In 2008, he provided assistance in testing [[fackue]]'s [[DC Dev ISO]]. Also in 2008, he helped fackue implement improvements on [[Takayama Fumihiko]]'s [[Gnuboy/DC]] port. 64efe6d20b0c5b8b4e52353aec9d3321a9e364a3 High Cube 0 977 2159 2023-03-02T01:52:47Z Unknown user 0 Created page with "Developer: g-funkster Version: 1 Last Updated: May 3, 2002 Description: A 3D puzzle game that is similar to Intelligence Qube for the Playstation. [http://www.dcemula..." wikitext text/x-wiki Developer: g-funkster Version: 1 Last Updated: May 3, 2002 Description: A 3D puzzle game that is similar to Intelligence Qube for the Playstation. [http://www.dcemulation.org/files/software/nerohigh.zip Nero Image] [http://www.dcemulation.org/files/software/dischigh.zip Disc Juggler image] [http://www.dcemulation.org/files/software/highp.zip Plain files] 4b5b1e053fa23e7692dcefa70ec14f90490efee9 Pelican MP3 0 978 2160 2023-03-02T01:54:11Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=Pelican MP3DC| image=[[Image:PelicanMP3.jpg]]| homepage=offline| price=£14.99 version=1.0| downloads=Not available for free|..." wikitext text/x-wiki {{Infobox_Dev_Information| name=Pelican MP3DC| image=[[Image:PelicanMP3.jpg]]| homepage=offline| price=£14.99 version=1.0| downloads=Not available for free| release date=unknown| author=[[Pelican]]| isactive=No }} Pelican's MP3 DC allows you to enjoy high quality MP3 music from your MP3 CD collection. No messy set-up required, just load MP3 DC, put in your preloaded CD-R with your favorite music and your ready to rock. Get more out of your Dreamcast with MP3 DC. It's easy to use and you can create your own playlists. = Full Review = With the Dreamcast put to sleep as a gaming system, devices like Pelican's MP3 DC Audio Player are never far behind. Well, I say that like it's always been so, but in fact this system could have some very interesting uses after it ceases to be viable as a gaming platform. It's a powerhouse for graphics, has a 56K modem, and Windows CE compatibility, so when everybody has played all the games they want to, they'll be wondering if their Dreamcast isn't just a doorstop. MP3 DC turns the Dreamcast into an MP3 jukebox, using the boot-disk technique where the DC starts up, you put in the MP3 DC like any other game CD, and then after some load time...voila! MP3 player! So, if you own a Dreamcast and like to play MP3s on your computer, here's your chance to bring them into the living room. Now, if you haven't really jumped into the MP3 world with both feet, here are some thoughts on what this might mean to you. Buying a Dreamcast to play MP3s is still probably the cheapest way you could have a good player. Portables are at least a couple hundred dollars, if not more, and PCs are more in the thousands. With the few MP3 'appliances' out there, be it household, office or in-dash car systems, the MP3 DC option ends up being an easily accessible and fairly cheap way to have a home audio system playing your MP3 disks. == Performance == MP3 DC has a very basic interface. You see all the MP3s on the disk, listed in order. By moving through with the D-Pad, you can select certain songs to add to a playlist, or just play the whole disk in order. Whether you play the disk in order or use a custom playlist, pressing (A) or (B) serves to start and stop playback. And, that's it. Disks can be taken out and swapped without restarting the DC, and the loading time for MP3 DC is very short. Sound quality seemed good, and any difference in sound quality on my stereo system is probably due to higher compression of an MP3 versus the CD Audio we're mostly used to hearing. == Features == *Turns the Sega Dreamcast into an MP3 player *Lets you choose a play-list or just play an entire CD *Registers artist and song information on-screen if included with MP3 *No special memory requirements or additional equipment needed. == Drawbacks & Problems == One of the things that feels wrong about MP3 DC is the lack of control you have over playback options. Even the most simple PC desktop audio app will let you play in random order, but MP3 DC does no such thing. My idea of a 'playlist' is something that can be saved for later retrieval, and I really expected that MP3 DC would do something like this to let you pick even a few playlists from one disk that could be reused easily. Since so many MP3 files can fit on a standard disk, choosing a playlist can become overwhelming, and especially for a disk that has a mix of artists already, the way MP3 DC forces you into picking every single song on your playlist every time is tiresome. But, it lets you play MP3s, so how hard can you complain... There are really no options in the interface but play and stop, and while the easiest thing is just to accept that it won't replace some high-end DVD/MP3 5-disk changer, it also won't cost you 500+ dollars. The other item that might give you problems is that MP3 DC won't read CD-RW. Apparently, only CD-R is a readable format for DC, so be aware of that if you're considering this for purchase. The pricing on MP3 DC should end up at about where used DC games are now, so it's at least worth a shot if you already own the system. It's more than possible that devices and software like this will continue to show up for the DC, which really makes me happy as someone who bought the system not long before they canned it. I like the idea that my system has more going for it than games, but don't expect any frills on this bare-bones MP3 conversion kit. a6288b57731087df1801d2480f49e1da47f03ab9 File:PelicanMP3.jpg 6 979 2161 2023-03-02T01:54:30Z Unknown user 0 wikitext text/x-wiki PelicanMP3 e5d155841cf8a4913160bb403c6116983d5d5ada BombermanDC 0 980 2162 2023-03-02T01:55:05Z Unknown user 0 Created page with "BombermanDC beta http://www.dcemulation.com/dl/dl.php3?url=files/software/bombermandc122601.zip" wikitext text/x-wiki BombermanDC beta http://www.dcemulation.com/dl/dl.php3?url=files/software/bombermandc122601.zip 63a603afb07eeb1a3599af7fe009173e104c5819 BITmASTER32 0 981 2163 2023-03-02T02:03:36Z Unknown user 0 Created page with "== bITmASTER322 == bITmASTER32 was a German Dreamcast developer. He didn't release any software but he did many hardware hacks. He developed a IDE-HD Interface and found out..." wikitext text/x-wiki == bITmASTER322 == bITmASTER32 was a German Dreamcast developer. He didn't release any software but he did many hardware hacks. He developed a IDE-HD Interface and found out very interesting things about the Dreamcast hardware. Since his website went offline years ago, it was restored and put online again. bITmASTER's website can be found [http://www.maturion.de/dreamcast/bITmASTER32/dc/dc-index.html here]. a351107dab719b79b4be56ff0bc0c61bd70df239 Heinrich Tillack 0 982 2164 2023-03-02T02:04:23Z Unknown user 0 Created page with "A128, also known as Heinrich Tillack, was a German Dreamcast developer. He released [[DCASTLE]] and was working on [[KGL-X]] and [[Holly3D]]. He has quit the Dreamcast scene..." wikitext text/x-wiki A128, also known as Heinrich Tillack, was a German Dreamcast developer. He released [[DCASTLE]] and was working on [[KGL-X]] and [[Holly3D]]. He has quit the Dreamcast scene and is working on a racing game for the Nintendo DS now. *[http://a128.blogspot.com/ A128's homepage] bc471ad7e1fec33e3f4c5a83ad83053098ac05d4 KRYPT 0 983 2165 2023-03-02T02:04:58Z Unknown user 0 Created page with "kRYPT was a Dreamcast programmer. He released [[DCFactory]], a very well known selfbooting kit, DreamSNES ROMS.LST Creator and he also found out some significant technical det..." wikitext text/x-wiki kRYPT was a Dreamcast programmer. He released [[DCFactory]], a very well known selfbooting kit, DreamSNES ROMS.LST Creator and he also found out some significant technical details about the Dreamcast webbrowsers. An [[Interviews:kRYPT|interview]] with him is available. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=8049 kRYPT's Profile on DCEmulation] *[http://krypt.dyndns.org:81/ kRYPT's homepage] This interview was done by wraggster on 19th March 2002 for ConsoleVision.com. '''Consolevision: Where were you born, where do you live and what about your family?''' kRYPT: I'm 18 years old, I was born in St. Petersbourgh, of the former U.S.S.R., but I've been living in south-eastern Ontario, Canada ever since I was 8. Religion wise, my folks tell me I'm Jewish, and I smile and nod, but in reality I don't believe in any form of organized religion. '''Consolevision: What qualifications do you have?''' kRYPT: Officially, I'm a High School graduate, hoping to get accepted to University this year... unofficially, I have many years of experience programming various languages (*BASIC, Pascal, Turing, Perl, PHP), web design, as well as computer maintence and support. '''Consolevision: What made you get into computers?''' kRYPT: I thought it was kinda cool that you can make a box do whatever you want it to. '''Consolevision: What made you get into programming? What was your first program?''' kRYPT: I think my first program was a batch file, a menuing system I wrote for myself.. '''Consolevision: What projects/coding have you done previous to any Dreamcast programming?''' kRYPT: I've written numerous websites (MP3 Search Engines, Software Sites, and a few other things). I've also designed and implemented a scalable distributed application platform, upon which corporate intranet services may be based (unfortuately, due to compiler limitations of the language I wrote it in, it was abandoned). '''Consolevision: What got you interested in DC coding in the first place?''' kRYPT: I had this DC sitting around, and then someone told me I could play NES on it... ;) '''Consolevision: Your [[DCFactory]] is a great app for helping people, how do you see it progressing? and is there any features you would like to add to it?''' kRYPT: Well, It's currently marketed towards newbies, but I plan to gradually change that with the release of power-user scripts (such as an elf->bin wizard, and a directory -> self-boot cdi wizard). And of couse more applications will always be supported, as long as people continue to submit scripts ;) '''Consolevision: Do have any projects in the works? Or would love to do?''' kRYPT: I have a few projects in the works.. most promiment is a decent menuing system for the DC, so that multi-emulator CDs don't have to use (the kinda ugly) DemoMenu as an interface.. '''Consolevision: Apart from your own projects, has there been a homebrew game/project that you have played more than once? Or something that you can't wait to try?''' kRYPT: Nester is the thing that really brought me into DC emulation, and as such is my favorite project.. although DCDivx is starting to look appealing, once they get the bugs ironed out of it. '''Consolevision: What are you thoughts on the DC homebrew scene, How do you think it could be improved?''' kRYPT: Aside from the lamers, loosers, and whiners on the message boards, I like the scene, and enjoy being a part of it. People need to realize that nobody is doing any of this for personal profit, but rather because they want to, and to stop looking gift horses (such as DreamSNES) in the mouth. '''Consolevision: What's your opinion of the new super consoles like X-box, Gamecube, Game Boy Advance and the Playstation 2?''' kRYPT: I would never pay over $150 for a console, as I don't think a *console* should cost much more then that. If I want to buy a computer, I'll go buy a computer. If I want a dvd player, I'll go buy a DVD player. I think that some people may have a use for these all-in-one boxes, but I don't, and I don't think the games are so great that it justifies the investment. '''Consolevision: And the mandatory question.. What are your favorate games on every system you've owned?''' kRYPT: Bad Dudes and SMB2 (I spent weeks playing that) for the NES. Sonic the Hedgehog 2 for the Genesis. SF Rush 2049 for the DreamCast. Red Faction for the PC ;) ed0567ea4e0079fce8285e88809d57d715c57f34 File:FeetOfFuryScreen01 p.jpg 6 985 2166 2023-03-02T02:06:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Feet of Fury ingame screenshot 1}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ec070f1996798a8b5fac1da24d9d219e74e930d1 File:FeetOfFuryPackshot p.jpg 6 984 2167 2023-03-02T02:06:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=FeetOfFuryPackshot p}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 475de2606b20fc86f7d022e851ae6db728ac5118 File:FeetOfFuryScreen02 p.jpg 6 986 2168 2023-03-02T02:06:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Feet of Fury ingame screenshot 2}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0c9c08f21ff657dfbebf7d97690574d60970fe41 Feet of Fury 0 987 2169 2023-03-02T02:06:33Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="2" | {{{name|Feet of Fury}}} |- border="0" cellpadding="2" c..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="2" | {{{name|Feet of Fury}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="2" | {{{image|[[Image:FeetOfFuryPackshot_p.jpg|250px|thumb|Copyright: Cryptic Allusion]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|http://www.cagames.com/}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>Purchase</i>}}} |- stylbackground:#ffffff" |Release Date || {{{release date|06/07/03}}} |- style="background:#ffffff" |Author || {{{author|Cryptic Allusion}}} |- style="background:#ffffff" |Type of game || {{{type|Dance Dance Revolution Clone}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==Independent Review== [[Image:FeetOfFuryScreen02_p.jpg|thumb|left|320px|Copyright: Cryptic Allusion]] Written by MetaFox, October 22, 2005 Source: [http://web.archive.org/web/20060918192734/http://dreamon.cyberdogcastle.com/index.php?n=Main.FeetOfFury DreamOn/CyberDogCastle via Archive.org] In 2003, Cryptic Allusion Games made history by releasing the first commercial independent Dreamcast game written with free development libraries. We did some extensive hands on playing of the game, and sat down with the creators of the game, Dan Potter and Roddy Toomim for a quick Questions + Answers session regarding Cryptic Allusion, Feet of Fury, and their upcoming game, Tryptonite. (The Q+A will be available in the print version of Dream On, available in the fourth quarter of 2005) Feet of Fury is a dancing game that borrows many elements from Konami's Dance Dance Revolution Series of games. You have a set of arrows that you must follow, while keeping your steps to the music. The main difference of Feet of Fury, and the element that sets it apart, is that the game is focused more on strategy and beating your opponent. There are power ups and power downs on the board. Hitting an arrow that contains an icon may cause the speed of the arrows to slow down or speed up, or it might cause the arrows to reverse direction. [[Image:FeetOfFuryScreen01_p.jpg|thumb|right|320px|Copyright: Cryptic Allusion]] Because of this element, the multiplayer mode in Feet of Fury is awesome. Another addition is the health bar. At the end of the round, the person with the most health is the winner. It adds a lot more to this type of game when you have to worry about your opponent hitting you with powerdowns, and throwing your feet around on the dance mat like an idiot, all while trying to keep your health bar full. The single player mode is no slouch either. There are a good number of songs to play and unlock. Each song has a good tempo to it, and fits this type of game really well. There are a number of hidden characters and features to be unlocked, so the game will keep you entertained for hours. When you get sick of all that dancing, you can let your fingers do the dancing with what is in my opinion, the coolest thing to happen to dance games since their invention: The Typing of Fury mode. In this mode, letters fly up on screen instead of arrows, and you use your Dreamcast keyboard to match the letters to the beat while spelling out words. This mode is very challenging, and surprisingly, very fun. When you add multiple keyboards to the action for some multiplayer mayhem, you'll see the pure hilarity that ensues. This is a top notch addition, and is a lot less of a gimmick than you might think. Take your dusty underused keyboards out of the attic, and set them up for some furious typing, you won't regret it. Summary: Good songs, multiplayer battle elements, unlockables, and Typing of Fury make this game a good investment, and an example for future independent developers to follow. '''Overall rating:''' 4 / 5 Purchase it at the [http://www.goatstore.com GOAT Store]. 889ddb9d76c694e57cac16fa2ec265ac0cbe4eba LiENUS 0 988 2170 2023-03-02T02:10:04Z Unknown user 0 Created page with "This interview was taken by Wraggster for ConsoleVision.com. '''Wraggster: Where were you born, where do you live and can you tell us a bit about your family, etc?''' I was..." wikitext text/x-wiki This interview was taken by Wraggster for ConsoleVision.com. '''Wraggster: Where were you born, where do you live and can you tell us a bit about your family, etc?''' I was born in Baton Rouge, Louisiana and I still currently live there. My parents are divorced and my dad is remarried. I live with my dad and I have one sister who lives with my mom. '''Wraggster:What qualifications do you have?''' None actually, everything's 100% self taught. '''Wraggster: What made you get into computers?''' LiENUS: When I was about 10 my dad got a computer from some company called "Quantex". It was the worst computer ever, always breaking and such, so from that I was forced to always be repairing that computer. The most dissapointing fact about it was it had a winmodem. Then when I was 12-13 my dad ordered a new computer from gateway and I had him specificly ask for a non-winmodem. So from there I put Linux on my computer and after about a year I removed Windows 100%. '''Wraggster: What projects/coding have you done previous to any Dreamcast programming?''' Complete projects from start to finish done by me have been only in Visual Basic :/ I made a wingate clone called BitchGate (never released) and I made a sub7 client in VB that was only released to a few friends. As for other projects I've worked on with other people: The biggest is a project in Delphi that is still ongoing called VCS (Veterinary Care System). It was a custom program my dad had ordered for his veterinary clinic. He got a deal on it from the guy but the guy is never on so I end up supporting it most of the time. My contributions have been simple things like code cleanups and Bells/Whistles. Currently I'm working on porting the entire thing to Linux and removing its dependancies on some comercial controlls. '''Wraggster: What made you get into Dreamcast Development?''' Well, when the Dreamcast first came out in Japan a friend of mine was saying how cool it was. So when it came out in the USA I was one of the first people to buy one. Initially I only had a Dreamcast, a controller and Slave Zero (awesome game btw). Then slowly I got more Dreamcast accesories. Then sometime in 1999 (I think) Slashdot ran an article on the Dreamcast and they mentioned Marcus Comstedt's site (http://mc.pp.se/dc). I went there, got interested in Dreamcast programming, but at the time my cd-r drive was on the frits. So I asked for a cd-rw drive for my birthday, got it and when the BBA became available, I was one of the first people to order one ( ofcourse I still had to wait like a month to get it). Then when ipslave became available I began working on DreamAmp for the first time. '''Wraggster: How did you start and what programs did you use to start coding?''' Well, I started shortly after IPslave came out, so I of course used that. I also used GCC on Linux and [[libdream]]. '''Wraggster: Tell us about your Dreamamp player.''' reamamp is currently in a private beta, but I hope to have a completed release of that beta out by the 15th, because I leave for a week to Mexico then. The new beta supports numerous things, including Bug fixes that prevented it from loading beyond 7 files. I also have fixed non 44100 mp3 support, added the beginnings of bba/serial streaming support and added a VGA recenter support like in Smeg. '''Wraggster: Do you have any new projects in the pipeline ?''' I'd like to complete my modifications to libdream which include backport of kos vfs layer studio library malloc/free. I also have begun some (ie minimal) work on porting fpse to the dc thatl'l be a while before its released (if ever) '''Wraggster: What plans for the future do you have for Dreamamp?''' Possibly adding support for more file formats but beyond that I dont know. '''Wraggster: What programs have helped you on the dreamcast and how significant is a hardware opengl driver and to what programs emus would be made accessible with it? [[libdream]] has helped me as has dlmalloc (a malloc originally for the pc). As for the OpenGL driver it won't assist many emus except "lazy" ports where the person doesnt want to write a ta driver for the emu. as for programs lots! mainly things like a re-port of Quake or if the Quake2 source is released a port of that. but not much in the way of emus will be enhanced by it. Wraggster: What programs/apps/emus would you most like to see come out on the Dreamcast? Lienus:A re-port of Quake would be great the Quake available for the dreamcast right now is highly illegal. and as i said if the Quake2 source is released a port of that as for emus a psx emu for free would be cool. Wraggster: Whats your opinion of the new super consoles like X-box,Gamecube,Game Boy Advance and the Playstation 2? Lienus: X-box isnt all that great i've seen demos in eb it looks no better than a dc. Gamecube well i personally am thinking of getting one because i am a fan of zelda, GBA well the gb is the only handheld left however nintendos backwords compatible trip makes me scared that the gba is being held back by compatibility with the gbc. and playstation 2... well its by sony what else is there to say? it was majorly limited by sony not releasing a proper dev kit. it looks ugly as hell, and no proper anti-aliasing in the first gen games... even the homebrew devers have anti aliasing support on the dc. Wraggster: Which console looks the best for devving on? Lienus:The GBA because theres already flash carts out kos has been ported there. X-box would certainly be easy to develop on but its just a PC theres no challange or fun there. i am however interested in emulating the x-box and i think i may buy an X-box just for that theres a really nice 1ghz 128mb ram pc by hewlet packard and i think i could make a disk that you pop in there and bootup an X-box game and be able to play X-box games on it ,it would only work on that pc and it would require a removal of windows but i still think itd be cool. Wraggster:Your thoughts on the Dreamcast Emulation/Development Scene and how can it be improved? Lienus: If certain websites would stop carrying illegal software... other than that if a complete share of information is achieved and perhaps a lil bit more info would need to be gained on the TA. Wraggster: What are your favourite games for every system you have owned? Lienus: i started with a NES so for that prolly Duck hunt then i got a Genesis (still have this one) for that Sword of Vermillion then from there GB prolly Legend of Zelda GBC Legend of Zelda DX Saturn (Still have this one too and it works!!!) NiGHTS into Dreams Dreamcast (have 2 of these now!!) Dreamamp :) j/k umm prolly PSO (which is also my least favourite) .Thank you for your time it has been a honour for the scene. wraggster 50c973e05b0f9f1db2e2ab0ba882f1384dbbe764 Last Hope 0 989 2171 2023-03-02T02:20:30Z Unknown user 0 Created page with "== Features and Story == Taken from the [http://www.lasthope.ngdevteam.com/ Last Hope website]: ** ''Free 360° rotary protection unit for shooting and dodging enemy fire''..." wikitext text/x-wiki == Features and Story == Taken from the [http://www.lasthope.ngdevteam.com/ Last Hope website]: ** ''Free 360° rotary protection unit for shooting and dodging enemy fire'' ** ''Six stages with checkpoints'' ** ''Four difficulty levels'' ** ''Handdrawn NEO·GEO style backgrounds'' ** ''Fully animated CGI enemies'' ** ''Superb video game style soundtrack'' ** ''Constant 60 fps with up to 4 parallax layers'' ** ''Lighting and transparency FX'' ** ''Smooth plasma FX'' -> ''The evil empire is rushing at light-speed across the galaxies, heading towards Mother Earth. Barely 24 hours ago, they penetrated the last defense line of our galaxy, the Arsion Laser Belt. Millions of innocent people perished in outer space colonies. 70% of our fleet was destroyed during first contact. Our intelligence has now extrapolated their arrival within six days. Conventional weapons cannot stop them. Our last hope is in your hands: The Z-42 Warpstar. Warp into their territories and destroy their leader before they reach Earth.'' -> ''Last Hope is a shooting game with rotating satellite system and heavy influence by tactical game play. Memorizing level architecture and enemy patterns are necessary for further approaching. The satellite and the beam are the most important components of the game mechanics. You have to learn to deal with both techniques in interaction with the other. It is possible to rotate the protection unit in 360° around the playership and to engage it in 8 gradations. Just press "X" to shoot, "R-Trigger" to rotate clockwise and "L-Trigger" to rotate anticlockwise. The protection unit mainly serves the defense of enemy plasma projectiles and to fire a stronger plasma shot. There are four difficulty settings: very easy, easy, normal and hard. Less experienced players can enjoy the game on very easy and easy, while experienced players will enjoy the game on normal or challenging it on hard. There are a total of 6 stages. These vary from a sandily space laboratory, a channel fulfilled with muddy water, a idyllic landscape with floating continents, a soul melting enemy factory on fire to an eerily and muggy alien stage.'' -> ''Last Hope is comparable to classics like R-Type and Gradius. Yet it has it's own visual impressive graphic style and fresh game play. It also features a superb 16-bit digital audio soundtrack, which suits perfectly the games atmosphere.'' == Trailer Video == * [http://www.youtube.com/watch?v=LLzBfFz3YVs Last Hope Trailer on YouTube.com] == Reviews == '''Dreamcast Review''' by [http://www.dreamcast-scene.com/index.php/Main/LastHope-DCS-Review Dreamcast-Scene.com] '''Dreamcast Review''' by [http://segagagadomain.com/dreamcast-ntsc5/lasthope.htm SegaGagaDomain.com] '''Official NEO·GEO AES Review''' by [http://www.dreamcast-scene.com/index.php/Main/LastHope-Daddelkingz-Review Daddelkingz.de] (Translation) '''NEO·GEO AES Mini Review''' by [http://www.neo-geo.com/forums/showpost.php?p=1763248&postcount=158 Shawn, Admin of Neo-Geo.com]: -> ''I received the prototype of Last Hope from the developer in May of 2004 and considering the unknown source my expectations were quite low. Not 11 meg Digger Man low, but I wasn’t expecting to be wow’d, no pun intended.\\ I was immediately impressed with the graphics, sound effects, and the music. My 1st thought was that this must be some sort of port or rip from another system. No way would someone invest this kind of time into developing a game for the Neo without any solid reassurance of a release.'' -> ''Last Hope is a challenging shooter, not a game you can beat in one night, not even if set to easy mode. The play style is in the category of R-Type, Last Resort, and Pulstar, requiring a strategy to progress (memorization of patterns). When you die, you are ported back to a restart point, and there are multiple restart points per stage. I also remember power ups and add-ons for your ship, but not a life bar, so there is not much room for many errors. This is definitely a game that will require a long while to master.'' -> ''I also didn’t experience any glitches, which says a lot of time was already spent debugging. It’s clear that some talented programmers were involved in developing this new game and it would be a shame if it never saw some form of release.'' == DC Exclusives == Exclusive features only available in the Dreamcast™ version: * 16-bit CD soundtrack * VMU support (saving + visuals) * DC joypad + arcade stick support (R- and L-trigger support) * Use of DCs soundchips (64 channels/stereo) * Highres title screen Exclusive Dreamcast™ Game Modes: * Adjusted difficulty (Reduction of shoot frequency and flight velocity of enemy bullets / no ranking) * Explosions / particle effects reduced for more clarity on screen * Better hitting response for hit enemies * Improved visualization of boss hit zones == Notes == -> Straight from the [http://blog.ngdevteam.com/ NG:DEV Blog]: ''As the [[Neo Geo|NEO·GEO AES]] cartridge did well, we're now preparing a release of Last Hope on NEO·GEO CD and Dreamcast for December 2006*.'' ''Both versions will feature a [http://www.ngdevteam.com/download/lasthope_audio_sample.mp3 high quality CD Digital Audio soundtrack]. Dreamcast version will be a pixel perfect port with scanlines on 240p in progressive mode. Be sure that the game will run on NTSC and PAL systems on 60hz; Region Free. Just like every original Dreamcast game you can play Last Hope without any additional requirements.'' ''Currently we're negotiating with an publisher for world wide release.'' ''More words on this when time is given, so be prepared and subscribe yourself on one of following mailing list to stay up to date.'' ''Timm & René | info@ngdevteam.com'' Update: The [http://www.ngdevteam.com/lasthope_faq.htm FAQ] on the official site currently shows the release date (Dreamcast version) as January 31, 2007 . == Limited Edition == The Last Hope Limited Edition is strictly limited to 500 units and comes as a white multi-pack containing a extra soundtrack Vinyl-CD (with remastered full-length versions of the game's OST) and with an additional 4-page booklet with liner notes for the OST by [http://www.soniqfactory.com/index.html Rafael Dyll]. There's a special spine-card for the multi-pack box, and the game's manual now has 12 pages instead of the ten of the standard edition. The game's CD-ROM itself also features a different label. == The Soundtrack == The excellent soundtrack for the game was composed by [http://www.soniqfactory.com/index.html Rafael Dyll]: * [http://www.soniqfactory.com/downloads/assets/Dyll-LastHopeExcerpts.mp3 Last Hope Medley @ SoniqFactory.com] (3:59 min) * [http://www.lasthope-dc.com/data/lasthope_dc_audio_sample.mp3 Last Hope DC Audio Sample @ LastHope-DC.com] (4:17 min) ---- == External links == '''Info''' *[http://www.lasthope-dc.com/ Official Dreamcast Last Hope Site] *[http://www.lasthope.ngdevteam.com/ Last Hope Official Site] *[http://blog.ngdevteam.com/ NG:DEV Blog] *[http://www.lasthope.ngdevteam.com/#credits Credits] '''Downloads''' *[http://www.ngdevteam.com/download/lasthope_video_normal.zip MPG Trailer] *[http://www.ngdevteam.com/download/lasthope_medley.mp3 MP3 OST Sample] '''Official Websites''' *[http://www.ngdevteam.com/ NG:DEV.TEAM] *[http://www.soniqfactory.com/ SoniqFactory] *[http://www.redspotgames.com/ redspotgames] 5432d63662e63e0c8694249ac7f0a6811755147f Dream Photo Manager 0 990 2172 2023-03-02T03:00:33Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=Dream Photo Manager| homepage=[http://sourceforge.net/projects/ljsdcdev Homepage]| version=1.0.0| downloads= [http://sourceforge.net/projec..." wikitext text/x-wiki {{Infobox_Dev_Information| name=Dream Photo Manager| homepage=[http://sourceforge.net/projects/ljsdcdev Homepage]| version=1.0.0| downloads= [http://sourceforge.net/projects/ljsdcdev/files/Dream%20Photo%20Manager/1.0.0/DreamPhotoManager-1.0.0.tar.bz2/download Plain Files/Source Code]| release date=02/07/2009| author=[[BlueCrab]]| isactive=Sort of. }} Dream Photo Manager is the first homebrew program available to access the DreamEye camera for the Dreamcast, and was written by [[BlueCrab]] as a way to test the DreamEye driver for KallistiOS. It is a relatively simple program that only allows one to view and delete pictures from the DreamEye camera. = More Resources = *[http://dcemulation.org/phpBB/viewtopic.php?f=72&t=98503 Forum topic for discussion of Dream Photo Manager 1.0.0] 515839c1bb6fc3eabf5501baf9ad978f0724e94b Building KOS on MinGW-w64/MSYS2 0 991 2173 2023-03-02T03:01:47Z Unknown user 0 Created page with "==Overview== This tutorial is a step-by-step guide on how to setup a toolchain and KOS environment on your Windows system. The toolchain consists of a C/C++ compiler (GCC),..." wikitext text/x-wiki ==Overview== This tutorial is a step-by-step guide on how to setup a toolchain and KOS environment on your Windows system. The toolchain consists of a C/C++ compiler (GCC), assembler and linker (binutils), and C library (newlib). As the Dreamcast has two processors - the SH4 CPU and the AICA (ARM) sound processor - the toolchain includes compilers for both. KOS consists of the operating system core (kos) and a set of nicely integrated libraries (kos-ports). Since KOS was developed for Unix-compatible systems (like Linux, BSD, etc.), a Unix-compatible development environment must be installed. The available choices are Cygwin, MSYS and MSYS2. MSYS is unmaintained and out-dated. Cygwin and MSYS2 both work, but MSYS2 seems to be maintained more actively, work better and also offers a better package management system, so it is preferred. ==Preparations== Install MSYS2 from http://repo.msys2.org/distrib/i686 (this tutorial used http://repo.msys2.org/distrib/i686/msys2-i686-20160205.exe). ''Please make sure to use partition C:\''. A user reported issues of git, wget, etc. not working at all when installing to partition D:\. On the MSys2 website it's mentioned that FAT filesystems don't work, so that's an alternative explanation. As the setup completes, it will ask whether you want to open a shell. Don't. Open ''C:\msys32\mingw32_shell.bat'' instead (mingw shell instead of msys2 shell). ==Install script== At this point, please consider trying the install script first. It will perform the remaining steps below automatically. Download the install script: [[File:Kos_setup_script.zip]]. Then change to the directory of the script and execute it (uses Unix paths instead of Windows paths, ''C:\'' becomes ''/c/'') $ cd /c/Documents\ and\ Settings (''find your Download folder here..'') $ sh kos_setup.sh The script should perform all the remaining steps. If something goes wrong, you can try to continue the steps manually or ask for help on the forums/IRC. ==Install required packages== MSYS2 uses the ''pacman'' package manager. The following command should download all required programs. $ pacman -Sy --needed mingw-w64-i686-binutils mingw-w64-i686-gcc mingw-w64-i686-pkg-config mingw-w64-i686-libpng mingw-w64-i686-libjpeg-turbo diffutils git make subversion patch python tar texinfo wget ==Downloading KOS== KOS is available through a Git repository at SourceForge. The standard install directory assumed in the configuration files is /opt/toolchains/dc/{kos, kos-ports}. $ git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ==Toolchain (cross-compiler and libraries)== After cloning the KOS repository, run the toolchain download+unpack+compile scripts: $ cd /opt/toolchains/dc/kos/utils/dc-chain $ sh download.sh $ sh unpack.sh Then compile the cross-compiler and system libraries. The erase=1 will delete temporary files after a successful build. $ make erase=1 After this command completes successfully you have a working cross-compiler for Dreamcast and can compile KOS next. ==Setting up KOS== You should read the documentation in the kos/doc directory for details, but here are the basic steps required to set up the KOS environment: Go into the kos directory and copy the template configuration: $ cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Now edit environ.sh to match your installation. If you use the default installation directory you don't need to change anything. Execute the following command to set the KOS environment variables: $ source /opt/toolchains/dc/kos/environ.sh Remember to do this every time you want to use the KOS environment in a newly opened shell. Dont't forget to run the above command again when editing environ.sh. Now we are finally ready to compile KOS itself. In the kos directory, run: $ cd /opt/toolchains/dc/kos $ make ==KOS-Ports== KOS-Ports is a repository with commonly used libraries for development on the DC, like PNG or MP3 loading. Clone the repository: $ git clone git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Compile all KOS-ports using the build-all script $ sh /opt/toolchains/dc/kos-ports/utils/build-all.sh Now you should have a working Dreamcast development environment :-) Check out the examples in the KallistiOS directory to find out how to use KOS in your own projects! 0853f5579d1b2781140425053cd15f2e0a03d1db Building KOS on Cygwin 0 992 2174 2023-03-02T03:02:59Z Unknown user 0 Created page with "This is the old Windows setup tutorial, taken from a forum post by Ph3nom. Since then a new tutorial was written that uses MSYS2 instead. == Cygwin setup == # Install Cygwi..." wikitext text/x-wiki This is the old Windows setup tutorial, taken from a forum post by Ph3nom. Since then a new tutorial was written that uses MSYS2 instead. == Cygwin setup == # Install Cygwin 32bit, setup-x86.exe from here http://cygwin.com/install.html # Click next twice, making sure to install from internet. # Choose install directory. I chose d:\cygwin. Click next. # Choose download directory. Does not affect install directory. Click next 3 times. # Chose packages to install. I chose Devel, Libs, and Utils. [[File:Cyg01.jpg]] # Click next. When the download and install is completed (this can take some time), Cygwin should be good to go. == Toolchain (cross-compiler and libraries) == # Run 32bit Cygwin Terminal as administrator [[File:Cyg02.jpg]] # Download kos-2.0.0-src.tar.gz from here http://sourceforge.net/projects/cadcdev/files/kallistios/2.0.0/ # Create a folder /dc/ in your /Cygwin/usr/local/ folder # Create a folder /kos/ in your /Cygwin/usr/local/dc/ folder # Extract the contents of /kos-2.0.0-src/ into your /Cygwin/usr/local/dc/kos/ folder # Download [http://dcemulation.org/phpBB/download/file.php?id=754 this patch] and extract into your dc-chain folder # In cygwin, navigate to your dc-chain folder. Since I installed the chain on my d:, my command is $ cd d:/cygwin/usr/local/dc/kos/utils/dc-chain # Download the libs needed by dc-chain by running the script with this command: $ ./download.sh # Extract the libs needed by dc-chain by running the script with this command: $ ./unpack.sh # Patch the default kos install by running the script with this command: $ ./patch.sh # Build the dc-chain with this command $ make == KOS == # Download this [http://dcemulation.org/phpBB/download/file.php?id=755 environ.sh] and extract into your /Cygwin/usr/local/dc/kos/ folder # Navigate to your kos directory in Cygwin. Since I installed the chain on my d:, my command is $ cd d:/cygwin/usr/local/dc/kos # Configure your environment by running this command: $ . ./environ.sh # Build KOS by running the command $ make That's All! When kos is built, you are ready to start compiling your own code for the Dreamcast using Kos 2.0 and GCC 4.7.3. 9adbb28c3cc88d91f066ce80c5436c9a84534764 Development 0 2 2175 2143 2023-03-02T03:28:37Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === === Random Snippets === * [[Objdump]] c09a51dd5b9009bb5b23951c3ee15b7e16084df7 2186 2175 2023-03-02T03:53:34Z Unknown user 0 /* Website Development */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *Web Development Links === Random Snippets === * [[Objdump]] bbeb9cf81791e9ef0640466559ada65cd5e72e4a 2188 2186 2023-03-02T03:54:04Z Unknown user 0 /* Website Development */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Web Development Links]] === Random Snippets === * [[Objdump]] 08eafc10e55bd03a31accbcf6512b0ceb7907969 2195 2188 2023-03-02T03:57:54Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Web Development Resources]] === Random Snippets === * [[Objdump]] 5d3e03640d41c079438f11670e94700a49f68854 2197 2195 2023-03-02T03:58:18Z Unknown user 0 Undo revision 2195 by [[Special:Contributions/Rizzoislandgame|Rizzoislandgame]] ([[User talk:Rizzoislandgame|talk]]) wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Web Development Links]] === Random Snippets === * [[Objdump]] 08eafc10e55bd03a31accbcf6512b0ceb7907969 2198 2197 2023-03-02T03:59:17Z Unknown user 0 /* Website Development */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] f643e19525c860442d0bf61373d599e3fb8d264f Old tools 0 195 2176 2089 2023-03-02T03:46:19Z Unknown user 0 wikitext text/x-wiki __NOTOC__ This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] 401b325c94eec4292f3e5ee3372cc241a60c0529 2177 2176 2023-03-02T03:46:23Z Unknown user 0 wikitext text/x-wiki __NOTOC__ This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] e1e393557e1cfda39facf432c6d216c194d3d7f9 2178 2177 2023-03-02T03:46:45Z Unknown user 0 wikitext text/x-wiki __NOTOC__ This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) = Burning Applications = *[http://www.ahead.de/en/index.html#download Nero Burning Rom] - Burns .nrg images. If your burner supports Nero then you should use it. *[http://www.alcohol-software.com/download.php Alcohol 120%] - Burns .cdi images as well as many other formats. *[http://www.padus.com/downloads/demo.php Discjuggler] - Burns .cdi images. Nicknamed Discmangeler because so many people have problems with it. = Selfboot Kits = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dcfactory-0.9.5-FULL.exe DC Factory 0.9.5] - This is one of the best tools you can find for your DC, an all in one burning type program that utilizes scripts and auto updates, you can get the latest headlines from dcemu and everything. A must have for Dreamcast burners everywhere. *[http://www.dchomebrew.org/files/Sbinducr.exe Self Boot Inducer v2.1] - This program will uncompress and build a disc image from .sbi files. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/Selfboot.exe Selfboot] - A selfboot program by burnerO. It's a merger of Selfboot Buddy & Dir2boot. Small in size & easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dssbsfinal.zip DSSBS Final] - Disco Stu's Self Boot Solution. This is a popular DOS-based self-booting utility. It's small and easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_ultimate_selfboot_kitv4final.exe Ultimate Boot Kit V4.0 Final] - This program is very, very easy to use and supports bin2boot (data/data) method and the CDRecord (audio/data) method. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/selfboot.zip The Selfboot Kit Beta 3] - A selfboot kit by Roofus, it will currently create selfbooting CD's for DreamSNES, NesterDC, DCDivx & FreeSCI. *[http://www.dcemulation.org/files/needed/N&DG%204%20dummies%20vr2.exe Nester & DCGNUboy 4 Dummies] - A program put together by Jack_15, this is what he had to say about it: "Well here is the kit I made it is for NesterDC and DcGunuyboy it can uncompress roms that are on .zip and .rar file extensions. you don't have to put any thing in different directories the kit makes them for you!"- Version 2 Uploaded Now *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_quakedc_selfboot_kitv1.zip QuakeDC Selfboot Kit V1] - A program used to selfboot [[Quake|QuakeDC]]. It's another proggy from Pinoy2201 *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dreamboot1-2.zip Dreamboot 1-2] - A selfbooting program called DreamBoot, It has been tried out & it's good & easy to use, so if you've had problems getting programs like DCFactory, DSSBS Final etc. working on your system you might want to give this one a try. = Boot Discs = *[http://www.dchomebrew.org/Demomnu.shtml Demo Menu] - Loads emulators from [[Multisession_CD|multisession CDs]]. *[http://www.dchomebrew.org/dchakker.shtml DC Hakker] - Similar to Demo Menu but has a better GUI. = Various Tools = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/aspi.zip ASPI Layer Fixer] - Many people have problems with their burners, such as program not even detecting their burner or even not being able to burn at all. I recommend downloading this and using it if you have problems with any burning application on your system. *[http://www.dcemulation.org/files/needed/cdi2nero099.zip CDI2Nero] - Convert Discjuggler images into Nero format. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/CDmage1-01-II.zip CDMage] - This tool can open a CD image and extract files from it. Useful if there aren't any "plain files" for download. *[http://www.dcemulation.org/files/needed/elf2bin.zip Elf2bin] - Converts .elf files into .bin and scrambles/unscrambles bins. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dctool-1.0.exe DCTool 1.0] - A GUI wrapper for Scramble.exe and sh-elf-objcopy.exe by _kRYPT *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_scrambler.zip Pinoy2201's Scrambler] - A scrambler/descrambler & elf2bin converter. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] - An IP.bin logo inserting program. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] - A program that lets you insert your own logo into an IP.BIN. ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] beb4d1e2babc307e7cd361e552641078d57a5207 BigBoy 0 993 2179 2023-03-02T03:47:47Z Unknown user 0 Created page with "BigBoy was a Dreamcast developer. He released [[DC=64]] and [[DreamSpec]]. He was also active in the Xbox and PlayStation 2 scene. On April 18 , 2003, he announced that he sto..." wikitext text/x-wiki BigBoy was a Dreamcast developer. He released [[DC=64]] and [[DreamSpec]]. He was also active in the Xbox and PlayStation 2 scene. On April 18 , 2003, he announced that he stopped all of his homebrew and Dreamcast projects after a pc crash. We have [[BigBoy_interview|interviewed]] him several years ago. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=6872 BigBoy's profile on DCEmulation] *[http://classicgaming.dcemulation.org/ BigBoy's homepage] This is an interview with [[BigBoy]] that was taken in 2001 by Wraggster. '''DCEmulation: Please introduce yourself to the DCEmulation Audience.''' BigBoy: Lets leave it at Bigboy for just now.... '''DCEmulation: When did you start to get involved with programing for the DC?''' BigBoy: Let's just say it was "a few years back for a games company" '''DCEmulation: Why did you make [[DreamSpec]] - The Spectrum emulator for the DC?''' BigBoy: I made it so I can play Manic Minor on the TV again. '''DCEmulation.com: 007Cheater the Webmaster and founder of DCEmulation and one of my best online buddies told me that it's the most downloaded file now, what do you think of that?''' BigBoy: I see with the stats 007 put up, it's gotten quite a good recepion... LOTS of downloads, yeah I'm very happy with that, always nice when folk like what you do. '''DCEmulation: How much more work has to be put into [[DreamSpec]]?''' BigBoy: Wow!! LOTS... What's been released is in effect a weeks work! The Z80 core is from somewhere else, and the speccy part is dead simple... I need to optimise what I can, and get better timings as well...I also want to get a nice frontend, rather than the TEXT only one just now...in time 128,+2, +3 would be good too, I also need to add keyboard support, .Z80, .TAP and .TXZ supprt... '''DCEmulation: So you will need someone to help you design the frontend?''' BigBoy: Some pics yeah... that'd be nice...Yeah I liked the pics to the SNES one.... I'd kinda like that effect too... looks profesional :) '''DCEmulation: Would you like people to send you pics for the emu? You were refering to the graphics that Kathy Choi did for [[DreamSNES]]...''' BigBoy: Yeah... if you see the loading screen, something around that idea would be great currently 320x240 24bit is fine. An Intro piccy would be cool too, and a smart logo...? '''DCEmulation: So what are yur plans in the future for [[DreamSpec]]? BigBoy: little steps... I'll add more games each time... make it worthwhile burning... The current version has 17 games included on the disk that you can load and run... The new one will have far more games available... '''DCEmulation: When might the next release be?''' BigBoy: Next few days... I think it'll be cosmetic.... new games etc... I'd like some nice piccys to add though :-) '''DCEmulation: How long have you been around in the DC-Scene?''' BigBoy: err....a little over a week :-) '''DCEmulation: So it's very new to you?''' BigBoy: Yes, getting things working was a chore and a half... the tutorials aren't "quite" right yet :-) its good to see though! So many new folk getting into this kind of hardware is cool. The CD stuff I got from Marcus i think it was, was amazing... to have figured it all out is very cool... '''DCEmulation: What is your feeling about Utopia and the boot disk?''' BigBoy: Although... being in Games, I don't approve of copying them... I think it's great for development, and homebrew stuff. '''DCEmulation: What would you like to say to end this interview?''' BigBoy: Keep Emulation free.... '''I'd like To thank BigBoy for this very informative Interview.''' b62c0ee00178c2c4240c90e22a2ecefad1764613 File:Checker 201b.png 6 994 2180 2023-03-02T03:49:49Z Unknown user 0 wikitext text/x-wiki Checker 201b 3d0059dd9c51188d4cf811271f78c9d9dabe5833 1ST READ.BIN Checker 0 995 2181 2023-03-02T03:49:53Z Unknown user 0 Created page with "{{Infobox_Tools_Information| name=1ST_READ.BIN Checker| image=[[Image:Checker 201b.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=2.0.3a|..." wikitext text/x-wiki {{Infobox_Tools_Information| name=1ST_READ.BIN Checker| image=[[Image:Checker 201b.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=2.0.3a| downloads=[http://dchelp.dcemulation.org/?download=checker_203a.zip Binary]<br />[http://dchelp.dcemulation.org/?download=checker_203a_src.zip Source]| release date=8/15/2007| author=fackue| isactive=Yes }} The '''1ST_READ.BIN Checker''' is a tool that checks a Dreamcast binary file and reports if it's an unscrambled BIN, scrambled BIN, ELF, or SREC binary. It also serves as a front-end to convert files from ELF formats to binary formats. It uses ''scramble'' by [[Marcus Comstedt]] to scramble or descramble binaries and ''sh-elf-objcopy'' to convert ELFs into binaries. There also is a command line version available that is written in C. There are binaries for the current version, 0.1, for [http://dchelp.dcemulation.org/?download=checkerc-01-win32.zip Windows] and [http://dchelp.dcemulation.org/?download=checkerc-01-linux.gz Linux]. The [http://dchelp.dcemulation.org/?download=checkerc-01-src.zip source code] is also available. Mac users can compile 0.1 themselves or use the [http://dchelp.dcemulation.org/?download=checker_vb2c_osx.zip] original vb2c release binary. 7d9f87d22d6d0a4b3524aa4444099697ba2f06b3 2182 2181 2023-03-02T03:49:59Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=1ST_READ.BIN Checker| image=[[File:Checker 201b.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=2.0.3a| downloads=[http://dchelp.dcemulation.org/?download=checker_203a.zip Binary]<br />[http://dchelp.dcemulation.org/?download=checker_203a_src.zip Source]| release date=8/15/2007| author=fackue| isactive=Yes }} The '''1ST_READ.BIN Checker''' is a tool that checks a Dreamcast binary file and reports if it's an unscrambled BIN, scrambled BIN, ELF, or SREC binary. It also serves as a front-end to convert files from ELF formats to binary formats. It uses ''scramble'' by [[Marcus Comstedt]] to scramble or descramble binaries and ''sh-elf-objcopy'' to convert ELFs into binaries. There also is a command line version available that is written in C. There are binaries for the current version, 0.1, for [http://dchelp.dcemulation.org/?download=checkerc-01-win32.zip Windows] and [http://dchelp.dcemulation.org/?download=checkerc-01-linux.gz Linux]. The [http://dchelp.dcemulation.org/?download=checkerc-01-src.zip source code] is also available. Mac users can compile 0.1 themselves or use the [http://dchelp.dcemulation.org/?download=checker_vb2c_osx.zip] original vb2c release binary. d7c9741d9391b47e90477577abc7cfc1956610f6 SvOlli 0 996 2183 2023-03-02T03:50:51Z Unknown user 0 Created page with "SvOlli was a German Dreamcast developer and he released [[Stella DC|DCStella]]. We have an [[Interviews:SvOlli|interview]] with him on our site. *[http://www.svolli.org/softw..." wikitext text/x-wiki SvOlli was a German Dreamcast developer and he released [[Stella DC|DCStella]]. We have an [[Interviews:SvOlli|interview]] with him on our site. *[http://www.svolli.org/software/dcstella/ SvOlli's DCStella website] This interview was by DarthEmuFan on 3rd March 2002 for ConsoleVision.com. '''Consolevision: Where were you born, raised, personal details, etc?''' SvOlli: Born and raised in a small town called Lehrte near Hannover, Germany (the town of the Expo 2000 and the world's biggest computer fair, the CeBit). Moved to Hannover in May 2000. Only child, born '72, zodiac sign pisces, not married. '''Consolevision: What qualifications do you have? College degree's?''' SvOlli: Right now I'm writing my diploma thesis, but I already have several years of professional experience from jobbing which kept me off my diploma. Jobs includes ones from administration stuff to coding at Germany leg of the OS manufacturer QNX. '''Consolevision: What got you interested in computers?''' SvOlli: Hard to say. I've been hooked on tin-soldering by watching my dad. But I'm not nearly as good as him, though. After getting an Atari 2600 VCS, I was fascinated by the idea of the "virtual worlds" though they weren't called like that back then, in the C64 I saw the perfect combination of playing games and toying with technique behind it. That facination for the technique faded a bit away when the C64 went way out of state of the art. The last time I really used mine was 1992. From there I went to AMIGA, but couldn't really make good friends like I did with the C64, so my interest faded away another bit. It came back, when I got first contact with Unix (SunOS 4.1, to be more precise) on my studies at the univerity. Mostly the whole networking / remote stuff I got hooked on. I learned that there is a widely source code compatible free Unix for installation on PCs, called Linux (1.0.9 was my first self-compiled kernel). That got me into buying a PC, which I hated back then for MS-DOS and Windows 3.1. '''Consolevision: What project(s) have you done in the past?''' SvOlli: I'm still listed as a developer of sorcerer, a Linux distribution that's based on compiling source code when installing a package instead of using precompiled binaries. I put my work there on hold 'till my diploma's finished. In general you could say that I'd rather like contributing to other peoples projects, than beginning (and finishing) my own. If I think the software I use is lacking a feature, I'll take a look if I can hack it in there myself instead of asking the author to do so. The times I succeeded I sent the patches of my work to the original authors. Isn't that just a wonderful thing about open source software? I did that on several Unix utilities, including wmx, an X11 window manager. '''Consolevision: What made you get into the Dreamcast Homebrew scene?''' SvOlli: For gaming I got myself a PSX when the prices got reasonable. That one I built in an arcade cabinet once, running Namco and other museums. But then came the time I noticed that the PSX is too limited for a good allround emulator. My attempts on putting a PC in there resulted in two wrecked keyboards, so I looked for an alternative. I was playing Soul Calibur and other DC titles with a friend of mine, and he told me Mame is also available for DC. Since DCs are on the runout, they are cheap, so I bought one with Soul Calibur. Looking for Mamed I stumbled over the terms "coders cable" and other stuff concerning homebrewing software. DCStella was the very first thing I did on homebrewing after toying a bit around with KOS and dc-load and stuff. Seeing [d]cs2600 I was disappointed. I knew Stella for Linux and I liked that one much better, so I assumed that someone must have already ported it. Much to my surprise, my search was fruitless. And like every qualified villian states in the movies: "If you want get something done, you got to do it yourself." So I started to analyse the source on how to replace the screen output by the one on the DC. By just using the frame buffer it was not a very hard thing to do. The prove of concept was made. There was the birthday of the guy who got me into the DC in the first place was about 3 weeks after of my first sight of a running emulation. So I hacked the v0.1 (called alpha1) back then together quickly, and on his birthday I presented him a rather unimpressive 3"-CDR with the Atari Logo as the title saying: "This is the Stella Emulator for Dreamcast. I just ported it. This one here in my hand is the very first copy of it. Happy Birthday." - "Just a moment. Does this mean I can finally play the old Atari games in rgb quality like I always wanted?" - "Yep." - (then there was a twinkle in his eyes) "Cool." '''Consolevision: What made you choose to do an emulator for the Atari 2600 and how complex is it a machine to emulate?''' SvOlli: It was always the wish to have a DC version of Stella. I wanted to play some games of my childhood again, and I knew Stella for several years, I already poked around in the source once in a while when I got the time and was curious about some details of one or another 2600 game. So I knew the source was well organized and highly portable. And that's the point: I just did a port not a complete emulator. So I don't know a lot about emulation, the whole emulation just looks like a precompiled library to me that's called once for initialization and again once for every frame to process. '''Consolevision: Would you say that it is an easier to port emus over from linux rather than rewrite them specifically for the dreamcast?''' SvOlli: Definitively, yes. Graphics, sound and input need to be rewritten, but the core is still the same. This also can turn to a downside: I'm using some rather generic and not DC optimized source, so it'll be slower than a tweaked one. Have a look at the [[DreamSNES]] emulator: the machine they emulate is much more complex and it runs at roughly the same speed as [[DCStella]]. Awesome job done there. '''Consolevision: What programs have helped you bring Stella to the Dreamcast?''' SvOlli: About the same all others help to bring their software to Dreamcast: the gcc-toolchain done by [[M.R.Brown]], [[AndrewK]]'s [[dc-load]], [[Dan Potter]]'s [[KallistiOS|KOS]] and [[libdream]]. A texteditor for writing / modifying the source, nothing far apart from the tools I use for writing Unix sources. '''Consolevision: Do you have plans for updating [[DCStella]] or are you happy with what is an exceedingly good emulator already?''' SvOlli: Though I'm quite pleased with it like it is now, I still have some plans, but most of them I hold of until I finished my diploma thesis, since they could prove to be rather time consuming. First of all I want the VMU image to be also themeable, probably even themeable for each ROM loaded. Second would be a monitor to go searching for cheats, because I want to play Solaris to the end someday. There are also open issues to be solved, like the paddles and the sound that's just not like the original Stella. I'm still curious of the feature requests that will come in the future, like the one ROM autostart feature would never have gone in, if nobody asked. But there are already some requests that I had to turn down, like support for 7800 games, since I only do (and only want to do) the port of Stella, there's no real ambition to supercede the emulation capabilities of the original Stella. Well, I've implemented an illegal opcode in the original Stella sources though, but that's an exception to the rule and was also rather easy to do. But these changes have already been submitted for inclusion on the original Stella. '''Consolevision: The themeable VMU images, surely that is a massive undertaking, would you seek help from the dreamcast scene to make them?''' SvOlli: Not really. That's something I'd like to hack in there myself. On the other hand if someone reads this, likes the idea and sends me a patch, it will go in there and save me work. But that's not help I seek out for. Where I really could use help is the darned paddles routine. It refuses to work and after several days of bug-hunting I still have no idea what's broken. Maybe I'm blind for the obvious, maybe it's some typecasting or endian problem, I just don't know. Finally one could say that porting Stella has is small enough for a project where someone could do all by himself, but it's still big enough for others to offer their ideas. That's one of the ideas in releasing the source: if someone has a cool idea and some skills, he can download the source, see if his idea you work, without the need to ask me for anything. That's something that bugs me about most of the DC homebrew releases: I have an idea for a feature but fail to see if it's really doable, since I can't take a look at the sources. If it wouldn't be for Dan Potter, each homebrewer would be forced to reinventing the wheel. '''Consolevision: Whats your favourite Atari 2600 game and why? :)''' SvOlli: I don't have that one game, since my taste changes quite often in details, but it's always something that's unique to Atari 2600 in idea and gameplay like Adventure or Haunted House. Or maybe some of these cool party two player games like Combat, Outlaws or Pele Soccer. The game I will be spending on most time in 2002 is going to be Solaris, since I want to beat that one with all it includes: drawing maps and stuff :) '''Consolevision: Would you consider doing any other projects for the dreamcast or for that matter the Game Boy Advance for that matter?''' SvOlli: Yes, absolutly. I want to do my own mp3 player using KOS and the mp3/oggvorbis libraries, since I want one that's also usable without the need for a monitor, so all output will be displayed on the VMU. Linux on DC is also something very tempting for doing a quick hack like porting FreeCiv, for example. But setting up a cross compiling suite for Linux is a bit more difficult than for a bare cross compilation kit, like it's needed for KOS and libdream. And Linux would be also a quite nice platform to see if porting of software would make sence. I'm thinking about VICE for example. If that Commodore emulator runs painfully slow on the DC one can skip the try in porting it to KOS. The other ideas I have are rather the result of sheer need, like I need some software for backing up the VMU, so if no one does it until summer I'll hack a tool together that allows you to save and load your vmu over dc-load. About the GBA I'm not so sure, I guess if I want something portable to toy around with, I'd rather go for a Linux-PDA. '''Consolevision: Wow, you have some great projects and we wish you luck :) What's your opinion of the Dreamcast scene and the fact that through people such as your self we the fans can play great vintage games on a state of the art console?''' SvOlli: Thanks. When Sega chose the name Dreamcast I'm they didn't think of it as the "Dream" of the homebrew scene. But imho it is, it's the platform with the best access for homebrewers and people using their work: no modifications needed for booting homebrew CDs, developer's cable for $25 and enough infos on the web to get started without bothering anybody. That's what I did, that makes it a dream. About the fans enjoying my work I'd like to say that you're the one pushing the project forward. Over 1300 diffrent machines (ips) from the internet downloaded DCStella V0.2, V0.2a and V0.2b from my site in February. That's encouraging. Overall it's a nice community to participate in, though some more homebrewers wouldn't hurt. The only sad thing is that at the end of 2002 it will be dead on the commercial scene like any other discontinued system. History repeating itself there: bad concepts seem to sell better, just take a look at VHS, Microsoft and even Sony's going to get in line with them. Someone once said that the Dreamcast is like the Amiga of the console world. There's no comparison on the Dreamcast that could be more true and that gives me hope, since no one dies harder than an Amiga die hard, or a DC die hard for that matter :-). '''Consolevision: For the last question: What would be the emulator/homebrew software etc you would most like to see appear on the Dreamcast?''' SvOlli: VICE! What's lacking now is a good C64 emulator, and VICE is the best portable of them all, just one single assembler line (and that one's in the DOS port), and already ported to six platforms, have a look at http://viceteam.bei.t-online.de/ There's also some other stuff that I would like to see more evolving, like ScummVM for example. If I take a look at the site promoting open source projects like freshmeat.net or sourceforge.net, I feel like a child in the candystore not knowing what to pick first. And there's also one thing I'd like to see more happening on the DC homebrew scene and that's more sharing of the source. 92e8acf1fd8bb69d7ce6f7a6fd7b2c129ab3c8b3 DemoMenu 0 997 2184 2023-03-02T03:51:56Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=DCGrendel| homepage=No longer online| version=1.4b0| downloads=[http://dcemulation.org/1-newsdump/Applications/demomnu-1.4b0.tar.gz Plain F..." wikitext text/x-wiki {{Infobox_Dev_Information| name=DCGrendel| homepage=No longer online| version=1.4b0| downloads=[http://dcemulation.org/1-newsdump/Applications/demomnu-1.4b0.tar.gz Plain Files & Source]<br/>[http://dcemulation.org/1-newsdump/Applications/demomnu-1.4b0-cdi.zip DiscJuggler image]| release date=09/19/2001| author=DCGrendel| isactive=No }} This is used for having multiple bins on one disc -- you use this app to select which one to execute. It also has a built-in S3M player. d01ed54b514d52183bb6d8f60db9482eef8657cf Bero 0 998 2185 2023-03-02T03:52:21Z Unknown user 0 Created page with "Bero was a Japenese Dreamcast developer. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=12341 Bero's profile on DCEmulation]" wikitext text/x-wiki Bero was a Japenese Dreamcast developer. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=12341 Bero's profile on DCEmulation] 4a202a601f5eee24a9c1922d445ab47db7228f7d Freeware homebrew games 0 76 2187 2036 2023-03-02T03:53:59Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[ArmoredCampaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[SonicRoboBlast2|Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 7e00ad77b3e6ec136c459862b7dacb06a4de2cc3 File:3di-1.png 6 999 2189 2023-03-02T03:54:51Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=3di-1}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} aa84e65cfdca51eae527c18b87c99fe3fecaac26 File:3di-2.jpg 6 1000 2190 2023-03-02T03:54:51Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=3di-2}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f0fc7f8c7580c1ee47fd10bb02b9fe4e12f0e6a5 File:3di-3.jpg 6 1001 2191 2023-03-02T03:54:51Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=3di-3}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} cc84af9952546d5f6853766373ec45dad06eab10 3D Invaders 0 1002 2192 2023-03-02T03:55:31Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://axlen.com/dc/3di/1st_read.bin.gz Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' [[Image:3di-2.jpg|220px| 3D Invaders]] [[Image:3di-3.jpg|220px| 3D Invaders]] '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [http://axlen.com/dc/3di/1st_read.bin.gz Plain Files], [http://web.archive.org/web/20060614012847/http://www.dchomebrew.org/files/plain/3di-bin.zip Alt.] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di-src.tar.gz Source], [http://www.boob.co.uk/files/3di-src.tar.gz Alt.] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] 97540665ba6d2a8a82b95f580093e6c8e85bf1b6 Chuck Mason 0 1004 2196 2023-03-02T03:58:11Z Unknown user 0 Created page with "Chuck Mason was a Dreamcast developer. He released [[gleam!]], a NES emulator. He was also involved in the development of [[xNES]], an NES emulator for Linux." wikitext text/x-wiki Chuck Mason was a Dreamcast developer. He released [[gleam!]], a NES emulator. He was also involved in the development of [[xNES]], an NES emulator for Linux. 0f218fcbdfcd9587e488cc75c0c0dc1230305815 Web Development Resources 0 1005 2199 2023-03-02T03:59:23Z Unknown user 0 Created page with "=== Known Working Webpage Builders: === *Microsoft Frontpage 2000 and Below (must turn off all addtional addons such as DHTML and CSS) *Dreamweaver 4 and Below === Web Develo..." wikitext text/x-wiki === Known Working Webpage Builders: === *Microsoft Frontpage 2000 and Below (must turn off all addtional addons such as DHTML and CSS) *Dreamweaver 4 and Below === Web Development Resources: === * [https://web.archive.org/web/20031205061600/http://dreamcast.planetweb.com/community/homepages/dcdesign.html DC Design (dreamcast.planetweb.com)] * [https://web.archive.org/web/20020124162819/http://tools.planetweb.com/ PlanetwebMaster] * [https://web.archive.org/web/20181029115530/https://dreamcastarena.com/how-to-create-dreamcast-website-friendly Dreamcast Arena (Javascript Dreamcast Scripts)] === Known Compatible Hosting Sites: === *[https://www.hostgator.com/ Hostgator] 6deb91f82f7a3a6460e1081d07f7e7edc97d3d7d 2204 2199 2023-03-02T04:04:41Z Unknown user 0 /* Web Development Resources: */ wikitext text/x-wiki === Known Working Webpage Builders: === *Microsoft Frontpage 2000 and Below (must turn off all addtional addons such as DHTML and CSS) *Dreamweaver 4 and Below === Web Development Resources: === * [https://web.archive.org/web/20031205061600/http://dreamcast.planetweb.com/community/homepages/dcdesign.html DC Design (dreamcast.planetweb.com)] * [https://web.archive.org/web/20020124162819/http://tools.planetweb.com/ PlanetwebMaster] * [https://web.archive.org/web/20181029115530/https://dreamcastarena.com/how-to-create-dreamcast-website-friendly Dreamcast Arena (Javascript Dreamcast Scripts)] * [https://bswirl.kitsunet.org/outil/dc/?lg=en&menu=on BlueSwirl Dreamcast Tools] * [https://www.angelfire.com/pa3/VAMPMAN/krypt_dcinfo.html DC Browser Reverse Engineering Project] === Known Compatible Hosting Sites: === *[https://www.hostgator.com/ Hostgator] d760632866d75f0047c9726d63596ab179c8d83b 2229 2204 2023-03-02T04:38:36Z Unknown user 0 Darc moved page [[Development Resources]] to [[Web Development Resources]] wikitext text/x-wiki === Known Working Webpage Builders: === *Microsoft Frontpage 2000 and Below (must turn off all addtional addons such as DHTML and CSS) *Dreamweaver 4 and Below === Web Development Resources: === * [https://web.archive.org/web/20031205061600/http://dreamcast.planetweb.com/community/homepages/dcdesign.html DC Design (dreamcast.planetweb.com)] * [https://web.archive.org/web/20020124162819/http://tools.planetweb.com/ PlanetwebMaster] * [https://web.archive.org/web/20181029115530/https://dreamcastarena.com/how-to-create-dreamcast-website-friendly Dreamcast Arena (Javascript Dreamcast Scripts)] * [https://bswirl.kitsunet.org/outil/dc/?lg=en&menu=on BlueSwirl Dreamcast Tools] * [https://www.angelfire.com/pa3/VAMPMAN/krypt_dcinfo.html DC Browser Reverse Engineering Project] === Known Compatible Hosting Sites: === *[https://www.hostgator.com/ Hostgator] d760632866d75f0047c9726d63596ab179c8d83b File:Ipwriter 012.jpg 6 1006 2200 2023-03-02T04:00:46Z Unknown user 0 wikitext text/x-wiki Ipwriter 012 62c998c30e70ea34c810bdd6eb01d38b703166c7 IP.BIN Writer 0 1007 2201 2023-03-02T04:00:54Z Unknown user 0 Created page with "{{Infobox_Tools_Information| name=IP.BIN Writer| image=[[Image:Ipwriter_012.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.1.6a| downlo..." wikitext text/x-wiki {{Infobox_Tools_Information| name=IP.BIN Writer| image=[[Image:Ipwriter_012.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.1.6a| downloads=[http://dchelp.dcemulation.org/?download=ipwriter_016a.zip Binary]<br />[http://dchelp.dcemulation.org/?download=ipwriter_016a_src.zip Source]| release date=3/18/2008| author=fackue| isactive=Yes }} Use this tool as your all-in-one [[IP.BIN]] tool. It can do all of the following: view\extract\update [[IP.BIN]] and [[IP0000.BIN]] data in CD images, view\extract both in CD-ROMs and view\extract\add [[MR logo|MR logos]] in IP.BINs. No other IP.BIN tool can do all this! 35d7ecda63aef8d97e587af5326b64e8645a49de 2202 2201 2023-03-02T04:01:04Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=IP.BIN Writer| image=[[File:Ipwriter_012.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.1.6a| downloads=[http://dchelp.dcemulation.org/?download=ipwriter_016a.zip Binary]<br />[http://dchelp.dcemulation.org/?download=ipwriter_016a_src.zip Source]| release date=3/18/2008| author=fackue| isactive=Yes }} Use this tool as your all-in-one [[IP.BIN]] tool. It can do all of the following: view\extract\update [[IP.BIN]] and [[IP0000.BIN]] data in CD images, view\extract both in CD-ROMs and view\extract\add [[MR logo|MR logos]] in IP.BINs. No other IP.BIN tool can do all this! ce012d4dc3df31a290ccd7b3261a24484afacddb Spiderette 0 1008 2203 2023-03-02T04:03:28Z Unknown user 0 Created page with "A card game. http://www.dcemulation.com/dl/dl.php3?url=files/software/spiderette.zip" wikitext text/x-wiki A card game. http://www.dcemulation.com/dl/dl.php3?url=files/software/spiderette.zip 9bac5f063159c929001f39d9126a8c4908fc4f31 File:Blazemp3.jpg 6 1009 2205 2023-03-02T04:06:55Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Blazemp3}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 9eba6e0e77ae2c42f8adf4d0dbe9a835d53cedb0 File:DC MP3.gif 6 1010 2206 2023-03-02T04:06:55Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=DC MP3}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 4c7b2bd67eccceb2e18dac71a4148e0b19a00dba Blaze MP3 0 1011 2207 2023-03-02T04:07:27Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=Blaze MP3DC| image=[[Image:Blazemp3.jpg]]| homepage=[http://www.blaze.de Homepage]| price=£14.99 version=1.0| downloads=Not avail..." wikitext text/x-wiki {{Infobox_Dev_Information| name=Blaze MP3DC| image=[[Image:Blazemp3.jpg]]| homepage=[http://www.blaze.de Homepage]| price=£14.99 version=1.0| downloads=Not available for free| release date=unknown| author=[[Blaze]]| isactive=No }} ==About== Blaze MP3DC allows you to play MP3 CD's on your Dreamcast console! Create your own playlists and display the song and artist being played. Also includes free 100 track MP3 CD. *Easy to use - plays CD based MP3 files *Plays files of any size - plays VBR files *Includes CD and file browser [[File:DC MP3.gif|thumb|left]] = Full Review = Are you still listening to CDs as they were ten years ago? You know, 72-some-odd minutes of music, just enough to fit Beethoven's 9th Symphony, yadda-yadda-yadda…. Then you're commiting a crime that's suarre to send thousands of data compression majors into a fit of poorly constructed Huffman encoding trees. See, they got this new thing called MP3. You can encode your music into MP3 form, reducing your typical four minute track down to around six-or-so megabytes. Do the math - a single CD can now hold over a hundred tracks of high-quality audio. Of course, if you can live with reduced sound quality, you can make the music files even smaller and can pack even more onto a CD. Such is the power of MP3, kids - it's not just for illegal downloads. So now you've got a CD full of MP3 music, but how to play the thing? You have four options: #Play the CD back on your computer. This works, but you're stuck listening to the music while you use your computer. No good. #Buy an MP3 CD player. Yikes! Over one hundred bucks! No good. #Stick the CD up to your ear and turn it real fast. Maybe, just maybe, you'll hear something. Uhh… never mind. #Obtain the "Blaze MP3 DC" for a mere $19.99. Ladies and gentlemen, we have a winner. Brought to us by Blaze, the same company behind the DC-X import player and the DC Twin Joystick, the MP3 DC allows you to play MP3 files stored on a CD on your Japanese or American Dreamcast (we haven't tried it with a European Dreamcast, but it should work as well). You simply stick the MP3 DC start-up CD in your Dreamcast, swap it with a CD loaded with your favorite MP3s, and you're ready for hours of music. To get you started, Blaze has included a CD with the package that features around 100 MP3 tracks. For those interested, here are some of the higher-tech aspects of the DC MP3 playback, as promised by Blaze: *Plays VBR (variable bit rate files) *Plays MP3s of any size *Plays Mono/Stereo files Of course, to have any real use for this product, you'll need to either have a source for CDs with MP3s of your favorite music (don't ask us where you can buy these - we'll have to report you to the feds), or have the ability to burn CDs with your favorite legally obtained MP3s. This latter step requires access to a CD burner, something that's standard on many computers and is readily available at any computer store. Once you have some CDs loaded with MP3s, the MP3 DC takes it from there. The software displays a list of MP3 files available on the disk. You can play individual files, or you can select a series of files for a play list. When a song is playing, the television displays the song and artist info if available. You can skip to the next track on your play list with just the push of a button, but that's about all you can do - there's no forwarding or rewinding through tracks, or pausing. Be aware when picking up the MP3 DC, that you're getting somewhat of an underground product. The interface for playing music is pure text, which may scare off some. Also, the MP3 DC software is on a CD, not a GD-ROM. If you have a newer DC, you may not be able to run it. Make sure the store you buy the MP3 DC from will allow you to return it if it doesn't work with your system. If you really want an MP3 CD player and don't mind a few rough interface issues, the Blaze MP3 DC is a good choice. [http://www.blaze.de/ Order It Online Now] abd7a62780e68d223d83b9911b6cbdff293c562a File:Dcmp3.jpg 6 1012 2208 2023-03-02T04:08:39Z Unknown user 0 wikitext text/x-wiki Dcmp3 98091c7ea8daf32e21e1e30ddcc0cdd4839eac13 DCMP3 0 1013 2209 2023-03-02T04:08:41Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=DCMP3| image=[[Image:dcmp3.jpg|250px]]| homepage=[http://www.maturion.de/dreamcast/dcmp3 Homepage]| version=1.13 beta| downloads= [http://..." wikitext text/x-wiki {{Infobox_Dev_Information| name=DCMP3| image=[[Image:dcmp3.jpg|250px]]| homepage=[http://www.maturion.de/dreamcast/dcmp3 Homepage]| version=1.13 beta| downloads= [http://www.dcemulation.org/files/software/dcmp3_13.zip Plain Files]| release date=09/13/01| author=[[Strat76]]| isactive=No }} DCMP3 was the first MP3-player for the Dreamcast and also one of the first applications for the Dreamcast by hobby programmers. It was developed by [[Strat76]]. '''Status:''' *Wallpaper(JPEG viewing) *ID3V2 bug fixed *Playlist creation *Playlist/.m3u file support *File browser(subdirs) *Play/Stop/Next/Prev/Shuffle *New gfx by Aeg2K, bigger fonts *Noise/bitrate/samplerate bugs fixed *Disc swapping *Screen saver. Blank screen after 3 min so you dont have to burn your TVs *Pause *Control changes: Start: Read rootdir / Shuffle On/Off in playlist mode, Y: Pause/Stop, A: Continue/Play = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = *[http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] *[[DCEmulation:IRC_Chat|Chat with others about this sofware]] *[http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] *[http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info = ( Check Readme File First!! ) #Burn all files in the zip to cdr root + your mp3 files in a "MP3" dir. JPEGs in a "JPG" dir.Make sure you have the "use folder names" option enabled when extracting the zip. The disc should have a WINCE dir, MP3 dir, JPG dir and dcmp3.exe, 1st_read.bin, cube, ip.bin in the root. #File options: Mode1, ISO level2, joliet. (I use Nero) #Boot with Utopia bootdisc, then swap to DCMP3 disc. #Use the pad to select song/m3u and press A 9097bf0be1b11ba4bcf427f6329646255cac8b11 2210 2209 2023-03-02T04:08:46Z Unknown user 0 wikitext text/x-wiki {{Infobox_Dev_Information| name=DCMP3| image=[[File:dcmp3.jpg|250px]]| homepage=[http://www.maturion.de/dreamcast/dcmp3 Homepage]| version=1.13 beta| downloads= [http://www.dcemulation.org/files/software/dcmp3_13.zip Plain Files]| release date=09/13/01| author=[[Strat76]]| isactive=No }} DCMP3 was the first MP3-player for the Dreamcast and also one of the first applications for the Dreamcast by hobby programmers. It was developed by [[Strat76]]. '''Status:''' *Wallpaper(JPEG viewing) *ID3V2 bug fixed *Playlist creation *Playlist/.m3u file support *File browser(subdirs) *Play/Stop/Next/Prev/Shuffle *New gfx by Aeg2K, bigger fonts *Noise/bitrate/samplerate bugs fixed *Disc swapping *Screen saver. Blank screen after 3 min so you dont have to burn your TVs *Pause *Control changes: Start: Read rootdir / Shuffle On/Off in playlist mode, Y: Pause/Stop, A: Continue/Play = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = *[http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] *[[DCEmulation:IRC_Chat|Chat with others about this sofware]] *[http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] *[http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info = ( Check Readme File First!! ) #Burn all files in the zip to cdr root + your mp3 files in a "MP3" dir. JPEGs in a "JPG" dir.Make sure you have the "use folder names" option enabled when extracting the zip. The disc should have a WINCE dir, MP3 dir, JPG dir and dcmp3.exe, 1st_read.bin, cube, ip.bin in the root. #File options: Mode1, ISO level2, joliet. (I use Nero) #Boot with Utopia bootdisc, then swap to DCMP3 disc. #Use the pad to select song/m3u and press A 73e25c1100296004db73945a2de4138396e54b64 Blaze 0 1014 2211 2023-03-02T04:09:21Z Unknown user 0 Created page with "==Blaze== Blaze was a British/German software developer and created cheating software. For the Dreamcast, they released [[Blaze MP3]] and the [[XPloder]]. The company was bou..." wikitext text/x-wiki ==Blaze== Blaze was a British/German software developer and created cheating software. For the Dreamcast, they released [[Blaze MP3]] and the [[XPloder]]. The company was bought in 2003 by Mad Catz Interactive Inc. . cd30ac8ecd180d5b219ef02d0fecb2158cbe5de0 File:Aw-dc.jpg 6 1015 2212 2023-03-02T04:15:34Z Unknown user 0 wikitext text/x-wiki Aw-dc a176d9d4dda8ddacf872513dea2b8f38705281ab RAW 0 1016 2213 2023-03-02T04:16:02Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | RAW |- border="0" cellpadding="2" cellspacing="1" align..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | RAW |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Aw-dc.jpg|thumb|280px| Another World]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/aw-dc_1.0.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|12/30/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|RAW}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Another World ''(Out of this World in the United States)'' is a classic action oriented platforming game created by Eric Chahi and released by Delphine Software. Gregory Montoir created an interpeter for Another World entitled RAW. RAW was shortly after shut down at the request of Eric Chahi, but permission was given for the GP32 and Dreamcast ports to continue, and the game data was permitted to be included in these ports by Eric Chahi himself. The original versions of RAW for the Dreamcast were ported by [[MetaFox]] (Mickey McMurray). When permission to release the game data with the interpreter was obtained, the project was handed over to [[GPF]] (Troy Davis). ==Downloads== * AW/DC 1.0 - [http://dcemulation.org/1-newsdump/games-demos/aw-dc_1.0.zip Plainfiles] - 12/30/2005 ==Links== * [http://gpf.dcemu.co.uk/ Troy Davis (GPF) Site] * [http://web.archive.org/web/20070124142934/cyxdown.free.fr/raw/ RAW Interpreter Site ''(Archived)] ae3cd1a16a6d2daa93aec36d8152cdcc45082029 File:GypPlay1.jpg 6 1017 2214 2023-03-02T04:19:24Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=GypPlay1}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} fed072bf3b567f3ed6127325b043d07b687f03d0 File:GypPlay3.jpg 6 1018 2215 2023-03-02T04:19:24Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=GypPlay3}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e27b315c30b56aed814adbd6ce19eddce9f6a75c File:GypPlay2.jpg 6 1019 2216 2023-03-02T04:19:24Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=GypPlay2}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8c37a41962e2a4e610d2a08322680e08dab217fb GypPlay 0 1020 2217 2023-03-02T04:19:30Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=GypPlay| image=[[Image:GypPlay3.jpg|right|250px]]| homepage=[http://gypplay.thegypsy.com/ Homepage]| version=2.0 Lik Sang Edition| downloa..." wikitext text/x-wiki {{Infobox_Dev_Information| name=GypPlay| image=[[Image:GypPlay3.jpg|right|250px]]| homepage=[http://gypplay.thegypsy.com/ Homepage]| version=2.0 Lik Sang Edition| downloads=[http://dcemulation.org/files/software/GypPlay_LikSangEdition.zip]| release date=03/05/01| author=[[TheGypsy]]| isactive=No }} __NOTOC__ GypPlay is a Dreamcast movie player by [[TheGypsy]] that allows you to play movies from a CD. The last version was released and optimized for the [[y2kode]] coding contest that was organized by [[Lik-Sang]]. == Supported Formats == *.mpg (MPEG-1 only) *.mpeg (MPEG-1 only) *.dat (MPEG-1 only) *.avi (no odd codecs!) *.m1v (MPEG-1 video, no audio) *.sfd (v1.01 SFD format works, but no audio. Newer SFDs not supported.) [[Image:GypPlay1.jpg|thumb]] [[Image:GypPlay2.jpg|thumb]] [[Image:GypPlay3.jpg|thumb]] == Download == {| |- |'''Format''' |'''Self-Boot''' |'''Type''' |'''Size |'''File Details ('''Need Help? [[Quick_FAQ|Click Here]]''') |- |[http://www.dcemulation.org/files/software/GypPlay_LikSangEdition.zip Plain Files] |No |ZIP |1.82mb |IP.bin included |- |[http://www.dcemulation.orgfiles/software/DcVideoSettings.mcf DCVideoFile] |No |ZIP |4kb |This is a TMPG video settings file. To be used with TMPGENC and sets PERFECT conversion settings when watching movies on your dreamcast. To use it press load at the bottom right in TMPG. |- |'''Tools''' |- |[http://www.dcemulation.org/files/software/TMPGEnc.zip TMPGEnc] |No |ZIP |1.2mb |A tool used to convert ANY movie you have to the correct dreamcast format. |- |[http://www.dcemulation.org/files/software/VideoCodecs.zip Video Codecs] |No |ZIP |1.5mb |A complete set of the three most used codecs on the net which include, smr, divx, mp42 and others. They include encodecs and decodecs so this adds more video support for the video conversion tools found here this is for PC only. |- |[http://www.dcemulation.org/files/software/mpeg2vcr.zip Mpeg2VCR] |No |ZIP |1.4mb |It's a util to convert Movie files which can be a nice alternative to TMPG it also has support for SFD format. |- |[http://www.dcemulation.org/?title=GypPlay.nfo Info File] | |N/A |N/A |For version 2.0 |- |} == Links == *[http://www.boob.co.uk B00B! Dreamcast Research] *[http://www.thegypsy.com TheGypsy.com] *[http://gypplay.thegypsy.com GypPlay.TheGypsy.com] == Covers == Covers for GypPlay can be found [http://dcemulation.org/covers/files/CD_Covers/GypPlay/ here]. bfd1c52c5978ff4c716dc235049018f80bdfb4d2 TheGypsy 0 1021 2218 2023-03-02T04:21:20Z Unknown user 0 Created page with "TheGypsy was a Dreamcast programmer. He released [[GypPlay]], one of the best media players for the Dreamcast. He is also known for hosting [[B00B! Dreamcast Research]], which..." wikitext text/x-wiki TheGypsy was a Dreamcast programmer. He released [[GypPlay]], one of the best media players for the Dreamcast. He is also known for hosting [[B00B! Dreamcast Research]], which was one of the biggest Dreamcast sites from 2000 until 2004. We have done an [[Interviews:TheGypsy|interview]] with TheGypsy. *[http://www.thegypsy.com TheGypsy.com] *[http://www.boob.co.uk B00B! Dreamcast Research] *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=7109 TheGypsy's profile on DCEmulation] This interview with [[TheGypsy]] was taken by Maturion on April 22, 2008. '''Why did you release GypPlay, what kind of problems have you had and how did you overcome them?''' I wrote GypPlay simply because I thought it would be interesting and fun to work on something for the Dreamcast. I had previous Windows coding experience, so the availability of the WinCE libraries on the Dreamcast made the learning curve much more gradual for me than would have been the case for non-WinCE development. Of course, one of the problems was simply lack of available details related specifically to the Dreamcast. I had some access to the leaked "official" devkit documentation, but even that was light on detailed information. There was some decent sample code, but most of it was very specific to one particular feature that they were trying to demo in that code snippet. Therefore, doing any real application that was complete still took a great deal of "guess and check" sort of development. Of course, that directly related to the second big problem: lack of any real development hardware. Developing for the Dreamcast at that early stage meant burning a lot of CDRs for testing. I probably went through 70-80 CDRs before I finally took the time to modify my Dreamcast to be able to read CDRWs. Also, at that time, a disc swap was required to boot the discs, so it put a lot of wear and tear on my Dreamcasts. I had one that I kept almost completely dismantled the entire time during development so that I could more easily do disc swaps and other such things. Later, the Utopia Boot Disc was released which did make development a bit easier (although it also opened up the world of game piracy that I was not overly fond of). If I recall, the first version did not work for booting WinCE-based discs, so it wasn't until a later boot disc release that I could actually make use of it to aid in development of GypPlay. '''How long did it take you to release GypPlay?''' I actually looked back through all of my notes and emails from that time period and was unable to determine exactly when I started development of GypPlay. I first started working on a WinCE boot loader that was intended to be used to download applications via a serial cable for testing. In the middle of that, I started with on GypPlay. My guess would be that I worked on it for around three weeks to a month before v1.0 was released about 3am on August 14, 2000. v1.1 followed about 12 hours later on the same day. '''Have you done anything else than GypPlay for the Dreamcast?''' I actually did some work on [[Boob!boy]], which was [[CyRUS64|CyRUS]]'s Gameboy emulator for the Dreamcast. To be honest, I have never been a big fan of emulators, so I did not want my name associated with it at the time. [[CyRUS64|CyRUS]] was having some trouble getting the controls to work smoothly, so I rewrote most of the controller code. I then asked him to not mention me helping with it. I should probably explain myself a bit about emulators since I know that they are very popular and stating that I am not a fan of them might not go over well. I'm actually a bit of a "purist" when it comes to certain video games. I actually collect the classic full-sized standup arcade games. I can't help but see things such as MAME actually hurting those old classics. Because of MAME, there are less people interesting in collecting the original machines. Granted, I understand that a lot more people can PLAY those old games now -- which I do see as a good thing -- but there is a price to be paid for that easy accessibility. Therefore, I've simply never been a big fan of emulation except in some rare circumstances. That being said, I will admit that I've become a bit of a hypocrite in that regard over the years. If I want to play a quick game of Mappy or Galaga, it is just easier to plug some current console into my HDTV upstairs and just starting playing than to go into the basement and try to fire up the actual arcade machine. But, now and then, I still do it just for that classic experience. '''How was the feedback of the scene to [[GypPlay]]?''' Initial response from most people was excellent. The ability to easily play MPEG video from the Dreamcast and have it be relatively smooth and stable was something that a lot of people were very interested in. That, of course, was mainly from an end-user standpoint though. From within the development community, there was some backlash from people that would prefer that no SEGA or Microsoft libraries be used. Of course, I would have preferred that too but, at the time, I simply couldn't have done it without using those libraries. Non-official SDK based information was scarce and just beginning to be discovered. Plus, I did have a "real job" that I needed to attend to, so my time was limited. In the end, I made friends with many of the ongoing homebrew Dreamcast coders and long-term feedback about GypPlay seemed to remain encouraging from both them and the end-users. '''Did SEGA ever try to contact you?''' I actually made the first move and contacted SEGA. After [[GypPlay]] had been released to the public and was getting quite popular, I started to worry a bit that it might have developed a large enough following that SEGA or Microsoft would take an interest and pursue legal action against me for distributing some of their libraries needed to use it. I found a post from John Byrd, who was the Director of Development Technology for SEGA at that time. I sent him an email from my real email address telling him that I was the author of GypPlay and asking if SEGA would be willing to discuss some sort of licensing agreement so that a hobbyist release like GypPlay could be distributed without legal issues. While working out the distribution rights would be difficult, they at least wanted to get me legal as far as having access to the SDKs was concerned. So, they sent me the paperwork that included the SEGA NDA (Non-Disclosure Agreement) and Developer Tools Agreements from SEGA and M icrosoft. They signed me up as an official independent Dreamcast developer. As far as I know, I was the only such person registered that way. This was in late September of 2000. SEGA stated that they were working on a "kind of hybrid open-source license" that would allow hobbyist developers to release software such as GypPlay. Unfortunately, this never came to be. Microsoft had released information regarding the XBox by this point, which meant that SEGA had very little pull with them to try to encourage additional development on their competing hardware -- especially for open-source hobbyist projects that would make neither company any actual money. In any case, it took several months to get all of the paperwork taken care of. SEGA of America had to send all of the Developer paperwork to SEGA of Japan and to Microsoft to be signed. So, by the time everything was done and I was an "official" developer, it was January. I was then given access to SEGA's developer web site and their developer tools ordering system. I didn't have a lot of money at the time, so all I ever bought were a few DC mice to experiment with. Unfortunately, over the next six months, things fell apart at SEGA as far as Dreamcast development was concerned. John Byrd, my original contact, and most of the others had been terminated or otherwise left that part of SEGA. By July, there was officially no longer any engineering support from SEGA for the Dreamcast. I attempted to see if I might be able to get some of the leftover development hardware to continue and SEGA did make an attempt to do this, but the details could not be worked out before everything related to DC development was terminated. A few months later, even the official developer web site was closed. '''Why have you stopped developping (or at least releasing) new versions of [[GypPlay]]?''' Mainly lack of time. Plus, since no legal agreement could ever be arranged to be able to release a licensed version of [[GypPlay]], it meant that any future releases would also technically be violating the law. I was no longer in a place in my life that I wanted to risk that on an ongoing basis. Plus, I had won Lik-Sang's "[[y2kode]]" competition -- which included a free trip to Hong Kong for a week! That was really the culmination of everything related to GypPlay. I had done my best at the time, released that final version, and just felt that it would be best to move onto other projects (none of which were Dreamcast related). '''What do you think about the Dreamcast scene now?''' To be honest, I haven't followed much for the past few years. While I loved the platform itself, I can't help but feel that it is mainly past its prime even for homebrew development. There just aren't enough end-users left to appreciate an author's work. Someone could release an excellent game or application for the Dreamcast today and there simply wouldn't be enough people around to really use it. There is still a great cult following, of course, but nothing like those glory days when you could release something and see hundreds of downloads that very first afternoon and thousands over the next few days. '''Do you plan to return to the scene one day and maybe release a new [[GypPlay]] version?''' This would be very unlikely. Life just happens and people find that they have other things that they would like to do. Now and then, I like to dabble in some console development just to see what is out there, but it is not something that I dedicate a great deal of time to any more. I really had a great time working with the Dreamcast and with the many people that contributed a great deal to make homebrew development possible (Dan Potter and Marcus Comstedt immediately come to mind), but most of us have since moved on and will have to simply rely on our fond memories of the machine. '''I would like to thank [[TheGypsy]] for this nice interview!''' 9b911e92a400b35ad0ccc55bce2190a16639287f Jim Ursetto 0 1022 2219 2023-03-02T04:22:16Z Unknown user 0 Created page with "Jim Ursetto was a Dreamcast homebrew developer. He ported [[TuxNES-DC|TuxNES]] to the Dreamcast." wikitext text/x-wiki Jim Ursetto was a Dreamcast homebrew developer. He ported [[TuxNES-DC|TuxNES]] to the Dreamcast. 1943cd0fc7ded252e59bd6e58c0e8d9cbb600bd1 Gonzo 0 970 2220 2150 2023-03-02T04:22:45Z Unknown user 0 wikitext text/x-wiki Gonzo was a Dreamcast programmer from Austria. He released [[(D)Colem]] and [[odd-DC]]. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=6867 Gonzo's profile on DCEmulation] This interview with [[Gonzo]] was taken back in 2001 by Wraggster. '''DCEmulation: Can you tell us a little bit about yourself?''' Gonzo: I'm 19 years old and from Austria. Still student at a higher school for informatics. '''DCEmulation: What's your programming history?''' Gonzo: I started 4 years ago with C,C++. In the following years I learned (Visual) Basic, Java and PHP. '''DCEmulation: What projects are you currently doing?''' Gonzo: 2 days ago I would have said "nothing" but in the last 2 days I started porting 2 new emulators. The first one is a Odyssey 2 emulator(port of O2EM). It's already running but there are some problems(no sound and only 4k rom support). The second one is a port of Virtual VCS , a Atari2600 emu without sound support. That one is running too on the DC but i have problems with the graphics output and controller input. And I'm still working on [D]Colem. These are the DC projects. Theres also a PC project I'm working on with 2 friends. It's a massive multiplayer online game programmed in Java. But thats another story... '''DCEmulation: What interest do you have in the dreamcast dev scene?''' Gonzo: It's a hobby so I think I should say fun. But it's also about learning. It's much easier to learn something new if you are doing something you like. PC programming is boring but programming for the DC is much more fun. DCEmulation: What future projects, if any, are you looking into? Gonzo: [[DreamSNES]] 1.0 and [[tubooboos]] PC Engine emu (great console!). '''DCEmulation: Why did you choose the Colecovision console to emulate?''' Gonzo: It wasn't already emulated on the DC and the source was well written and documented. And it has a great version of Donkey Kong... '''DCEmulation: Do you see the dreamcast scene progressing much further or do you think it has reached its peak?''' Gonzo: It's just the beginning. Existing emulators will progress and there will be new ones wich emulate newer consoles. I wouldn't be suprised if PSX,N64,Neo Geo or similar emulators will find their way to the DC. I don't think that emus like this are going to run in fullspeed or play commercial games but maybe somegames would be playable. At least with an PSX emulator. '''DCEmulation: Whats your viewpoint on the Bleemcast Emulator from a technical standpoint?''' Gonzo: Bleemcast is awesome and worth the money. It shows whats possible on the DC when it comes to emulate newer machines. Oh and i would kill someone to have a look at bleemcasts sourcecode. Such power makes me curious. '''DCEmulation: What do you think of the dcemulation website?''' Gonzo: I think it's a good source for the users to get their infos and emulators. From the developer's view it's not too helpful. Obwohl it's getting better with people like Heliophobe or Akira and some other devers visiting the forums. Oh yeah and it's nice to see that dcemu is getting rid of the illegal stuff like ******* . a6d3624b2a2ae3ef704e6acc55e21afd8fe6c130 File:Catandc.jpg 6 1023 2221 2023-03-02T04:23:49Z Unknown user 0 wikitext text/x-wiki Catandc 41354d00b5e1cf0173ccef2634e2bf826437c0b0 ReGex 0 1024 2222 2023-03-02T04:24:01Z Unknown user 0 Created page with "[[Image:catandc.jpg|thumb|CatanDC]] ReGex was Dreamcast programmer. He released [[FrNES]], a good NES emulator, and was working on [[CatanDC]], a Dreamcast implementation of..." wikitext text/x-wiki [[Image:catandc.jpg|thumb|CatanDC]] ReGex was Dreamcast programmer. He released [[FrNES]], a good NES emulator, and was working on [[CatanDC]], a Dreamcast implementation of the popular German board game "The Settlers of Catan" ("Die Siedler von Catan") but never released it due to data loss after he moved to a new city. In 2004 he sent out an email: ''Hey Sander, ''I thought I would let it die for a number of reasons. About a year ago when I moved I suffered a *big* data loss, 1 whole HD containing my entire development environment, and the current version of the CatanDC source (the last archive I had was from months before, lots of the engine was lost and I was so frustrated that I didn't even want to look at the website or anything anymore.. and just leave it as it was). That's the end of the story,really. I just was so frustrated that I didn't have the will to redo all the parts I'd lost (which were the really advanced features like Multi-VMU and the actual game engine.). ''Thanks for your interest, and at some point I may consider releasing whatever source I had built.. I just don't feel like digging it up and reliving the upsetness I feel towards the project at the moment. ''-Matt Alex (ReGex) ==Links== *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=5139 ReGex' profile on DCEmulation] *[http://archives.dcemulation.org/ReGex/ ReGex Web Presence (Archived)] This is an interview with [[ReGex]] that was done in 2001 by Wraggster. '''DCEmulation: Can you tell us about yourself and where you are from and what's your job, school etc?''' ReGex: I'm 22 years old, and I've been living in Calgary, Alberta Canada my whole life. I'm a Mechanical Engineer, and I graduated from the University of Calgary last year with a BSc.. I'm currently working on my Master's degree in Design Engineering. I am currently writing a conference paper, and my thesis. I help teach a couple courses at the university (mechanical simulation and artificial intelligence). '''DCEmulation: How long have you been into computers and more specifically coding? [Beware... long answer]''' ReGex: I started programming around the mid 80's when I was a little kid. I'd always been interested in robots and spaceships and stuff from the movies, and my Dad told me all about computers and that, because he's a Mechanical Engineer (and an accomplished programmer) as well. My Dad gave me some books on how to program, and some of those old books with code listings you could type out to get these little BASIC games to play. I did that up until I was about 12 and lost interest in it (I was much happier to play my NES). I stayed out of serious programming until around 1994 (although I did a bunch of little projects along the way), because there was a resurgance of interest for me when I got into the Demo Scene. I took Computer Science in High School (with a great teacher, Helen Koch) and learned Turbo Pascal. Between getting into demos and learning compsci, I joined a local demo group called Skyfire, and we started doing intros and stuff for our BBS. When I graduated High School, our group broke up and I focused on school. I got really good summer work (from the best boss I could have had, Doug Slack) at an oil company doing some little apps for Windows, and I cleaned up my C/C++/Win32 skills there. I also read Michael Abrash's books at that time, which are really good if you're interested in learning how to code hardware level graphics (at least in a pre-accelerator context). I also worked for a commercial software company, Objectworks, for a summer. Now I am developing software to accompany my thesis, and of course my DC projects. '''DCEmulation: What made you choose the Nes and the PcEngine To Emulate?''' ReGex: I really love both the systems... perhaps the NES a little more than the TG/PCE. I actually wanted to do the port of Hu-Go first (because I want to play Blazing Lazers on my DC), and have *technically* been working on it since November. I wanted to do the NES, because the system is really cool, and also that progress on the port of Hu-Go was going *so* slowly... mostly because of my own inexperience with embedded hardware. '''DCEmulation: What problems have you had and how did you overcome then?''' ReGex: Sound was *really* hard to do for [[FrNES]]. It was funny that [[NesterDC]] 3.0 released like the day after I got sound working, after I'd put all that work into doing it myself. To get through it, I just sat down for 2 weeks, warmed up the ol' coder's cable and debugged for 4-5 hours a night. Add some Slinky + Ninja Tune CDs to the mix and you have the recipe for success. '''DCEmulation: With 2 more emus being written for the Nintendo Entertainment System and up to 3 being written for the PcEngine has that made you more determined to complete your project and also have you teamed up to overcome problems that have been halting your progress?''' ReGex: Determination is in short supply over here :D My work requires me to use most of my quality brain-time there, so it's rare that when I come home, I'm all psyched to code. I would like to see my projects all be finished well, before too long (it would be nice before the end of 2001) but I'm not promising anything. Other emu's are somewhat of a concern, admittedly, but most of the projects I do are for my own enjoyment first, so I don't care *that* much if someone releases before I do. There has been a fair amount of code sharing going on between myself and other devvers in #dcdev. '''DCEmulation: When youve reached the end for this project, do you have any new projects in mind?''' ReGex: Well, when I'm done both FrNES and the TG/PCE emu, I might like to help out on some other project... I'd like to help out on something like crt0's OpenGL stuff... My brother and I have a top secret homebrew game in development, but it's not ready to be talked about yet. '''DCEmulation: What is your favourite Dreamcast emulator?''' ReGex: I'd have to say Bleem GT2, because I've logged more hours with that than I probably should have (took a week away from [[FrNES]] 0.50 :D)... I really like [[DreamSNES]]. I use [[FrNES]] a lot (even though I'm a little biased). '''DCEmulation: What is your favourite game for The Nes and also the PcEngine?''' ReGex: I'd have to say Contra on the NES, and Blazing Lazers on the PCE. '''DCEmulation: What is your opinion of the Dreamcast Scene, DCEmulation, and what would you do to improve it to make it more accessible?''' ReGex: I think the DC scene may have shrunk recently, but I don't really mind. Some of that shrinking might be due to Selfbootbuddy (and that everyone is burning their selfboots on the first try.. and not bothering people in the forums...but that's just my theory :D). I think Dan Potter and his group are doing fantastic work (without which I wouldn't have been able to do mine), and they are keeping things alive. Their work is indispensible and really superior. Dcemulation is a good gateway, and I always go there to check for news and stuff... I think improving updates on a daily basis would definitely help bring more people in on a regular basis. I like the idea of tournaments and stuff with DCE... I haven't played Q3A in a while :D '''DCEmulation: What is your view on the other new super consoles and the possibilitys of hobbyist development on them ie gba etc?''' ReGex: GBA is cool... I have one myself, and would love to do some coding on it. (Check out Loopy's version of his NES emu for GBA.. it's super sweet!). Gamecube looks cool,. but I'll suspend judgement until someone figures out a programming backdoor. PS2 is a maybe (until there's a way of stably getting one modded for development, I wouldn't consider it). '''DCEmulation: May I say thank you for your time and good luck with your project on behalf of DCEmulation and the rest of the emulation scene.''' Regex: Thanks Wraggster, always a pleasure. 364ca2c8f456ebc2c180a293eed3e2c235f25d65 File:NGDEVTEAM Logo.jpg 6 1025 2223 2023-03-02T04:32:41Z Unknown user 0 wikitext text/x-wiki NGDEVTEAM Logo ede2db162fc416608f28abcf4d8851871ea761ef NG:Dev.Team 0 1026 2224 2023-03-02T04:32:46Z Unknown user 0 Created page with "[[Image:NGDEVTEAM Logo.jpg|right|300px]] '''NG:DEV.TEAM'''(Stands for Neo-Geo Development Team) is an independent video game studio founded in 2001 by brothers René Hellwig..." wikitext text/x-wiki [[Image:NGDEVTEAM Logo.jpg|right|300px]] '''NG:DEV.TEAM'''(Stands for Neo-Geo Development Team) is an independent video game studio founded in 2001 by brothers René Hellwig and Timm Hellwig, based in Germany. The company is best known for ''[[Last Hope]]'', in addition to developing games for [http://www.en.wikipedia.org/wiki/neogeo NeoGeo], the team has ported their games to Dreamcast. == Games for Dreamcast == * [[Last Hope]] 2007 * [[DUX]] 2009 (as a HUCAST.net game) * [[Fast Striker]] 2010 == See Also == [[Rene Hellwig Interview|NG:Dev.Team 09/09/10 Interview]] == External links == * [http://www.ngdevdirect.com/index.php?osCsid=1e2debab72309faa849f85d96d80191a NG:Dev Direct] * [http://ngdevteam.com/index.php?option=com_content&view=frontpage&Itemid=54 official website] * [http://www.racketboy.com/retro/sega/dreamcast/2008/05/dux-new-dreamcast-shmup-game.html Interview with RacketBoy 2008] * [http://faststriker.com/index.html Fast Striker Website] * [http://www.redspotgames.com/ Game Publisher's Website] 11c949262811061c64ef1550c85e349849f41115 2228 2224 2023-03-02T04:34:24Z Unknown user 0 wikitext text/x-wiki [[Image:NGDEVTEAM Logo.jpg|right|300px]] '''NG:DEV.TEAM'''(Stands for Neo-Geo Development Team) is an independent video game studio founded in 2001 by brothers René Hellwig and Timm Hellwig, based in Germany. The company is best known for ''[[Last Hope]]'', in addition to developing games for [http://www.en.wikipedia.org/wiki/neogeo NeoGeo], the team has ported their games to Dreamcast. == Games for Dreamcast == * [[Last Hope]] 2007 * [[DUX]] 2009 (as a HUCAST.net game) * [[Fast Striker]] 2010 == External links == * [http://www.ngdevdirect.com/index.php?osCsid=1e2debab72309faa849f85d96d80191a NG:Dev Direct] * [http://ngdevteam.com/index.php?option=com_content&view=frontpage&Itemid=54 official website] * [http://www.racketboy.com/retro/sega/dreamcast/2008/05/dux-new-dreamcast-shmup-game.html Interview with RacketBoy 2008] * [http://faststriker.com/index.html Fast Striker Website] * [http://www.redspotgames.com/ Game Publisher's Website] The following interview was part of an open panel interview conducted by DC Emulation, Dreamcast-Scene and SegaBits. As part of our 09/09/10 Special. ---- [[Image:NGDEVTEAM Logo.jpg|left|300px]] ==About NG:Dev.Team== [[NG:Dev.Team]] entered the Dreamcast scene with 2007's NEO•GEO port [[Last Hope]]. With 3500 units sold, the game was a critical and commercial success, but considered rather difficult by many. In 2009, a reprint of Last Hope was released with the sub title "Pink Bullets". Based on fan feedback the game was heavily reworked and among other features offered easier game modes for less experienced players. This year on the 11th American anniversary of the Sega Dreamcast we caught up with NG:Dev.Team to discuss their upcoming game [[Fast Striker]] ==Interview== '''NG:Dev.Team has been around since 2001. Have you been working on other projects before Last Hope?''' ''Last Hope is our first finished full-scale game but we started a few other projects after Last Hope has been finished, one of them is Fast Striker that we have started at 2004 and has been released for NEO•GEO this year - proud 6 years after the project has started. It's hard to say the game got 6 years of development though, because to that time we considered game development rather as a hobby thing. We already accept pre-orders for a DC port of Fast Striker at [http://www.ngdevdirect.com NG:DEV.DIRECT].'' ''Release is Winter 2010. However, we started another project at 2003, a Jump 'N Shoot game that we want to release for NEO•GEO and DC in 2011. Rafael Dyll the composer of the Last Hope soundtrack is already contracted for music.'' '''So the Hellwig brothers are full time developers now?''' ''Yes we are a full-time developer now! We plan to have many houses and cars! ;)'' '''hahaha, well, as long as you keep giving us games...''' ''Fair enough!'' '''So, tell us about Fast Striker? How does it differ from the other shooters you have done?''' [[Image:FS Screens half dozen.jpg|right]] ''Fast Striker uses a different approach than Last Hope. With Fast Striker you get fast paced action and an elaborate scoring system, many people describe the gameplay to be fluid in contrast to Last Hope which is rather bulky. FS is rather a reflex shooter than a memorizer. We also took more for time for beta testing the game. We got some great help from many experienced players from communities like Triggerzone.de and Daddelkingzs.de to improve the game and make it a way more forgiving experience than LH too. The game also got shown on the Japan Expo in France (big thanks to eathis!), and on a big German shmup meet friendly hosted by Folke AKA Robert Garcia and the feedback has been very good.'' ''For us it also has been important to make the game as accessible as possible, so you can find 3 different game modes in the game. The Novice Mode is simply for beginners of the genre. The Original Mode is for experience players that prefer simple scoring systems and don't like to have too many bullets on screen. The Maniac Mode is for players that prefer complex scoring systems and many bullets on screen. But with all the complexity that the Maniac mode has, the game is still fluid and intuitive to play.'' ''Some people say the boss fights are too short, but once you make use of the technical bonus system they last longer. Example: The first boss has some pods on both sides - shooting them down takes more time to begin with, and the boss changes his attack once they're down. Another important factor of the game is the dynamic difficulty system (rank): You start on a low rank but the goal is to increase the rank as fast as possible to gain more score. The highest rank is Devil Rank. The scoring system is about grind beaming enemies and being close to the enemy. Holding the fire button gives you a blue laser, then focus on bigger enemies and the blue laser turns green. Now you're in the grind mode, and get more score for shooting up enemies. Try to be closer to enemy to gain more Kristalls, now rank up to Devil Rank and you're in scoring heaven!'' ''There's more detail on the scoring systems at our page: http://www.faststriker.com/mode.html'' '''How long does NG:DEV.TEAM plan on supporting Sega & SNK?''' ''Depends on the demand! So, yes we still have interest on such systems but the sales need to be right though.'' '''The NEO•GEO games are they licensed from SNK or are they as independent as Dreamcast?''' ''Nope, but we got quality approval from SNK/Playmore for Fast Striker. Y. Matsushita known from Twinkle Star Sprites has tested the game and he liked it. He told us a lot of good things about the game and has been nice enough to give us some tips to improve it. Unfortunately it has been too complicated to officially revive the NEO•GEO MVS though, so we didn't get a license. It's nice to have the praise and approval from the originators of the legendary NEO•GEO though, we are quite proud of this!'' '''What about Sega have they shown you any love yet?''' ''Nope.'' '''Have you considered following other indie developers such as Mad Peet and Senile Team and port your games to a digital service?''' ''Yes we know Senile Team, and it's nice to see they get R4 on WiiWare. Congrats to them. Btw, we want to get our NG:DEV.TEAM games on such platforms too. Pink Bullets is a hot candidate for it.'' [[Image:Fast Striker Box Arts.jpg|left]] '''How did you get involved with NEO•GEO development?''' ''Already in our childhood games like [http://en.wikipedia.org/wiki/Contra Contra 3], [http://en.wikipedia.org/wiki/Last_Resort Last Resort] and [http://www.en.wikipedia.org/wiki/thunder_force_iv Thunder Force IV] has fascinated us. Especially the NEO•GEO that brought the arcades in our living rooms. For us only has been a question of time until we tried to produce a NEO•GEO quality video game of our own. In 1999 we began to build the NEO•GEO development environment that consists of efficient and powerful Graphic, Map and Scripting-Tools as well as custom-built compilers for 68k and Z80. Our first goal has been to create our own adequate 2D game: Last Hope. In the 10 years before we collected experience with rather conventional and publicly documented systems like the [http://en.wikipedia.org/wiki/commodore 64 C64], [http://en.wikipedia.org/wiki/Amiga AMIGA 500] and [http://en.wikipedia.org/wiki/gameboy GBC]. During this long phase, both our requirements and our results have been constantly improved. '' ''As we consider the 16-bit video game ages as the peak of 2D video game culture, which is best represented by the NEO•GEO - it has been an obvious choice that we would develop for this console.'' '''...and how did that lead you into Sega territory?''' ''We found the DC to be a good choice for a port because it can handle 240p to keep the true NEO•GEO look, and because of the fanbase and their frothing demand on shooters. I also got something left for the DC, because from all current 3D consoles I spent most of the time with it. Games like PSO wasted my youth! :)'' ''When we had announced a port of Last Hope for DC we got contacted by Max Scharl from Van Basilco, now redspotgames. They published the game and for a world-wide distribution including Play-Asia etc.'' '''We would like to thank you for giving us the oppurtunity to interview you guys and we can't wait for Fast Striker. Is their a message you would like to give to the community?''' ''The game support of Sega Dreamcast depends on your support of indie developers!'' ''Thanks for your support!!'' [[Image:Fast Striker Coming Soon.jpg]] We would like to thank Rene Hellwig for taking the time for the interview. ==External Links== * [http://www.ngdevdirect.com/index.php?osCsid=1e2debab72309faa849f85d96d80191a NG:Dev Direct] * [http://ngdevteam.com/index.php?option=com_content&view=frontpage&Itemid=54 official website] * [http://faststriker.com/index.html Fast Striker Website] * [http://www.racketboy.com/retro/sega/dreamcast/2008/05/dux-new-dreamcast-shmup-game.html Interview with RacketBoy 2008] e8f12cd84e083c57ad507d753a03ca368d488bc6 File:Fast Striker Box Arts.jpg 6 1027 2225 2023-03-02T04:34:03Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Fast Striker Box Arts}} |date=2010-09-08 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8f63673c112d626f2bd3529879fa5daf2eca0f3b File:FS Screens half dozen.jpg 6 1029 2226 2023-03-02T04:34:03Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=FS Screens half dozen}} |date=2010-09-09 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} fb36a1c4710fb160e0c318813f1273b80584871d File:Fast Striker Coming Soon.jpg 6 1028 2227 2023-03-02T04:34:03Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Fast Striker Coming Soon}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 5e297346016cabe3091b4b8d1912c815652205e8 Development Resources 0 1030 2230 2023-03-02T04:38:36Z Unknown user 0 Darc moved page [[Development Resources]] to [[Web Development Resources]] wikitext text/x-wiki #REDIRECT [[Web Development Resources]] ee1d1d89f949637527a1b5704a43a81947b4bbd8 Excalibur007 0 1031 2231 2023-03-02T04:39:31Z Unknown user 0 Created page with "Excalibur was a Dreamcast programmer. He released [[XDP]], a web browser. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=12980 Excalibur007's profile on DCE..." wikitext text/x-wiki Excalibur was a Dreamcast programmer. He released [[XDP]], a web browser. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=12980 Excalibur007's profile on DCEmulation] *[http://www.psilocybindreams.com PsilocybinDreams.com] 40db4def2737cbcedf8e67f6f0d7062e9cd2b969 BlueCrab 0 1032 2232 2023-03-02T04:39:52Z Unknown user 0 Created page with "I'm not quite sure why anyone would really want to know about me, but in case they do here's a page. = Dreamcast Projects = * [[Ljsdcdev|ljsdcdev RPG]] - A 2D RPG engine for..." wikitext text/x-wiki I'm not quite sure why anyone would really want to know about me, but in case they do here's a page. = Dreamcast Projects = * [[Ljsdcdev|ljsdcdev RPG]] - A 2D RPG engine for Dreamcast and other targets (no longer maintained). * [[Ljsdcgen|ljsdcgen]] - A port of the Genesis emulator Generator to the Dreamcast with SDL (no longer maintained). * [[DCRPG]] - An enigma (no longer maintained). * [[Yabause]] - A Sega Saturn Emulator, ported to the Dreamcast. * [[CrabEmu]] - A Sega Master System, Game Gear, SG-1000, ColecoVision, CHIP-8, and NES emulator. * [[KallistiOS]] - A homebrew SDK for the Dreamcast. Used by many other homebrew projects, including all the ones listed above. = Dreamcast-related Projects = * [[Sylverant]] - An open-source server for the Phantasy Star Online series of games. ec31800da5019aa9fbb91158a9e37d02c5d88d94 File:Dreamarena1.jpg 6 1033 2233 2023-03-02T04:40:56Z Unknown user 0 wikitext text/x-wiki Dreamarena1 f2bcb5895075e236382097b3348e92acac7be252 File:Dreamarena.jpg 6 1034 2234 2023-03-02T04:41:06Z Unknown user 0 wikitext text/x-wiki Dreamarena 0c383c335e4ef92d08be1f5c62f17bb000f0d5e3 Dreamarena 0 1035 2235 2023-03-02T04:41:10Z Unknown user 0 Created page with "[[Image:Dreamarena.jpg]] [[Image:dreamarena1.jpg|thumb|Dreamarena]] The Dreamarena was the official Dreamcast online gaming service in Europe. It had around 500.000 register..." wikitext text/x-wiki [[Image:Dreamarena.jpg]] [[Image:dreamarena1.jpg|thumb|Dreamarena]] The Dreamarena was the official Dreamcast online gaming service in Europe. It had around 500.000 registered players and was closed down on officially on February 28th, 2003. Players were offered innovate features, such as message boards, an own email adress, game reviews, a shop, web-based games and much more. Here's a lit with all online games that were available in Europe: *Phantasy Star Online *Phantasy Star Online ver2 *F355 ChallengeU *POD Speed Zone *Speed Devils Online *Chu Chu Rocket *Worms World Party 271d6f8451b53883731573256273f833e37d557d 2236 2235 2023-03-02T04:41:29Z Unknown user 0 wikitext text/x-wiki [[File:Dreamarena.jpg]] [[File:dreamarena1.jpg|thumb|Dreamarena]] The Dreamarena was the official Dreamcast online gaming service in Europe. It had around 500.000 registered players and was closed down on officially on February 28th, 2003. Players were offered innovate features, such as message boards, an own email adress, game reviews, a shop, web-based games and much more. Here's a lit with all online games that were available in Europe: *Phantasy Star Online *Phantasy Star Online ver2 *F355 ChallengeU *POD Speed Zone *Speed Devils Online *Chu Chu Rocket *Worms World Party 5d562857090469a62ae2a54494dfd2b3b432ef04 Crt0 0 1036 2237 2023-03-02T04:50:48Z Unknown user 0 Created page with " Crt0 was a programmer for the Dreamcast. He released a wrapper library for libdream, called libdcgfx. He also released a port of id Software's Doom called [[DoomDC]] with D..." wikitext text/x-wiki Crt0 was a programmer for the Dreamcast. He released a wrapper library for libdream, called libdcgfx. He also released a port of id Software's Doom called [[DoomDC]] with [[DCGrendel]], which was the base for [[nxDoom]]. He also released a Bomberman Clone with [[Turrican2K]]. He released a port of id Software's Wolfenstein3D for Dreamcast. He was working on a Sega Genesis emulator with an assembly cpu core with Sayten. This emulator was never released. He later used the nick 'tr0ll'. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=6041 crt0' profile on DCEmulation] *[http://archives.dcemulation.org/tr0ll/ Crt0's website] Hello [[crt0]]! This interview was done by Platynum. '''DCEmulation: What motivated you to start developing for the Dreamcast?''' Crt0: Err...hmm...the first thing I wanted to do was to get Doom running on it as soon as I saw that there was open tools and libraries for the Dreamcast. '''DCEmulation: It was you, who first (to my knowledge) got OpenGL demos to run on the Dreamcast. Do you foresee OpenGL being used in a "full" game and it running at a decent speed?''' Crt0: Not really. The big problem is that I was using the default software rendering library. Its really slow, if someone wanted to write a PowerVR driver, it would be REALLY useful, anyone who knows OpenGL could code games much easier, but to use it in its current state a game would have to be of a quality not much higher than say Star Wars Arcade on 32x, and even that would be slow. '''DCEmulation: Wow . I have that game....kinda sucky thinking about it now... moving onto [[DCGrendel]] and your port of Doom do you think either of you will ever put in a multplayer mode or make it playable on the 'net?''' Crt0: I'll keep this simple. First, I'm not working on Doom anymore beyond the odd suggestion and code snippet (like for the fake surround sound that's in the latest version). As for multiplayer, it might happen in the future, probably over serial token link networking. As for over the net, unless someone releases really good specs for the modem, and unless either of us get BBAs, I wouldnt see it happening. '''DCEmulation.com: You recently joined/formed a demo group ...what are some demos you all are working on? Crt0: You all? :P uh. [[Turrican2k]] is working on an old school effects demo (color cycles and waves and etc. I haven't talked to him much recently, so I dont know what else). As soon as I get my TA problems squared away I plan on doing something really nice with that wave demo I showed a while back mainly, making it real time and adding other effects and I want to finish 500-tro someday :) '''DCEmulation: 500-tro?''' Crt0: 500-tro, the great dedication to the 500 Error DCEmu was so well known for :) '''DCEmulation: Do you see yourself forming a gaming company ?''' Crt0: :\. Not really. Coding has become a secondary interest at the moment . :\ '''DCEmulation: Thanx for your time, [[crt0]]''' Crt0: You are welcome 54214b19fd9456b1835214ca1b5a0ad50a9649f2 UDCDivX 0 1037 2238 2023-03-02T04:53:38Z Unknown user 0 Created page with "''uDCDivX'' is a DivX player for Dreamcast by [[Mekanizer]]. The latest version is v0.1, released on September 27, 2004. Download links: *[http://dcemulation.org/files/homeb..." wikitext text/x-wiki ''uDCDivX'' is a DivX player for Dreamcast by [[Mekanizer]]. The latest version is v0.1, released on September 27, 2004. Download links: *[http://dcemulation.org/files/homebrew/uDCdivx_ntsc.zip NTSC DiscJuggler image] *[http://dcemulation.org/files/homebrew/uDCdivx_pal.cdi.zip PAL DiscJuggler image] *[http://dcemulation.org/files/homebrew/uDCdivx_v01_ntsc.zip NTSC Plain Files] *[http://dcemulation.org/files/homebrew/uDCdivx_v01_pal.zip PAL Plain Files] 63778750eacb5bedda1872fb55454c5f4d5186c6 ToEleven 0 1038 2239 2023-03-02T04:54:11Z Unknown user 0 Created page with "To Eleven is an MP3 player for the Sega Dreamcast. Its user interface is displayed completely on the LCD screen of a VMU (meaning a VMU is required) so no television is necess..." wikitext text/x-wiki To Eleven is an MP3 player for the Sega Dreamcast. Its user interface is displayed completely on the LCD screen of a VMU (meaning a VMU is required) so no television is necessary to use it. This means that the Dreamcast can be hooked up to a high quality stereo system, even if it's not near a TV. However, if the Dreamcast is hooked up to a TV, the screen is used to display visualization of the music as it plays. To Eleven uses MAD to decode MP3s. To Eleven reads all MP3s off a separate CD, so it only needs to be burned once. The MP3 CD should have the MP3s burned to it as data, not audio. To Eleven supports directories and ID3 tags for organizing songs on CD. 596974770fc8cbf10cc2b190c79eb36610834595 MetaFox 0 1039 2240 2023-03-02T04:55:39Z Unknown user 0 Created page with "'''MetaFox''', also known as '''JenniBee''', founded [[Indie Dreams]], [[Cyberdog Castle]], and its imprint [[Cydoca Entertainment]], Dreamcast-Scene|Dreamcast-Scene America..." wikitext text/x-wiki '''MetaFox''', also known as '''JenniBee''', founded [[Indie Dreams]], [[Cyberdog Castle]], and its imprint [[Cydoca Entertainment]], [[Dreamcast-Scene|Dreamcast-Scene America]], and [[Dream On]]. MetaFox also posted news for [[DCEmulation:About|DCEmulation]] and [[DCEmu|DCEmu UK]], posted news for and was the third webmaster of [[Consolevision]], created art as a part of [[Screamcast]], and is the fourth webmaster of [[DC Evolution]]. ==Released projects== In 2000, MetaFox released the first DOS version of the emulator LASER, or Little Arcade Machine Emulator Releases, based on [[Mike Green]]'s SinVader. LASER was ported to the Dreamcast as [[LaserDC]] by Steven Harris, better known as [[ss_teven]], in 2001. In 2004, ss_teven overhauled the LASER codebase to utilize the portable development library [[SDL]], or the Simple Directmedia Layer. In 2002, MetaFox took over the development of [[DCGenerator]] from [[ATani]], a Sega Genesis emulator based on [http://www.squish.net/generator/ Generator] by [[James Ponder]]. In 2003, MetaFox released the first issue of ''[[Dream On Magazine]]'' at the [[Midwest Gaming Classic]]. Also in 2003, MetaFox released [[Single-game MAME releases|single game builds]] compiled with [[warmtoe|warmtoe's]] [[Maim]], a port of [http://www.mame.net/ MAME], or the Multiple Arcade Machine Emulator, to Dreamcast. MetaFox ran a yearly [[Sega Dreamcast]] coding contest known as the [[Dream On Contest]] every year from 2003 to [[2006]]. The contest was held jointly with [[The GOAT Store]], and the winners from the contest got their games published by GOAT Store Publishing. The winners, that were published by The GOAT Store, were ''[[Inhabitants]] ''and ''[[Maqiupai]]''. In 2004, MetaFox released a port of [[RAW]], an interpreter that played [[Eric Chahi]]'s ''Another World'', known as ''Out of this World'' in North America, and ''Outer World'' in Japan. In 2005, Eric Chahi graciously allowed Another World to be released on Dreamcast for free. The freeware version of Another World was released by [[GPF]]. A Dreamcast convention named [[DreamCon]] was created by and hosted by MetaFox in 2005 and 2006. The convention was held by Curt Grymala in 2007. For the 10th anniversary of the convention in 2015, MetaFox once again was the host. In 2006, MetaFox joined the team of the [[ScummVM]] adventure and role-playing game interpreter as a wiki editor, code contributor, and translator. Also in 2006, a compilation disc named [[The Sandman|''The Sandman'']] was released by the DC Evolution team with input from MetaFox. ''The Sandman'' was originally intended to be released as a companion CD for the second issue of the ''Dream On Magazine, ''but as that issue was postponed, it was released as a free compilation by DCEvolution. ''The Sandman'' included ''[[BurgerDC]]'', Screamcast's game based on ''BurgerTime, ''which was designed and programmed by warmtoe, contained music by [[DaMadFiddler]], and had art created by [[Krut]] and MetaFox. MetaFox's [[Sandmenu]] was developed for ''The Sandman'' compilation but was first demonstrated at the first stop of DreamCon in 2006. Sandmenu ultimately wasn't used in ''The Sandman'', but it was used in other compilations by DC Evolution, including ''[[Alice Dreams Tournament|Alice Dreams History]]''. MetaFox also created the Dreamcast Cygwin tutorial that [[fackue]] used when creating the [[DC Dev ISO]], which was released in 2008. In 2015, MetaFox released ''[[Indiana Jones and the Call of Thunder]]'', a fangame originally created by Dominik Haslinger, Jens Doblies, and Sebastien Ronsse, that was previously released in 2011 in source code form. The game was created with ScummGEN, a compiler for scripts written in SCUMM, or Script Creation Utility for Maniac Mansion. In order to make the game completable, MetaFox fixed bugs, added missing art, and expanded the storyline. MetaFox's expanded version was first released for Windows, macOS, and Linux using the ScummVM adventure and role-playing game interpreter. The game was released on Dreamcast later that year, using [[Marcus Comstedt]]'s ScummVM port, in a [[ScummVM|SCUMM Fan Game Compilation]] released by DC Evolution. ==Released game demos== In 1997, MetaFox released a 16-bit Windows version of an adventure game named ''[[The Adventures of Gus and Rob]]''. A one-room demo of a small-screen adaptation of ''The Adventures of Gus and Rob'' was released for the Neo Geo Pocket Color in 2002. In 2003, the first Dreamcast demo of the Dreamcast version of ''The Adventures of Gus and Rob'' was released for display at the Dreamcast-Scene booth at the [[Games Convention]]. ==Projects on indefinite hold== In 2002 Cyberdog Castle announced ''[[Mike Siecieska's Motocross]]'', which is considered to be on indefinite hold as no new information about the game was released after the announcement. In 2003, Cydoca Entertainment announced a maze game named ''[[Construction Obstruction]]'' and ''[[Dream'N'Play]]'', a program that would enable game creation on the Dreamcast without programming knowledge. Nothing further has been revealed about either project, so they are both on indefinite hold. Cydoca Entertainment took pre-orders for a party game known as ''[[Chikugoyaku]]'' in 2004, but a hard drive crash caused the project to be postponed and refunds were issued. Pre-orders for the second issue of ''Dream On Magazine'' were also taken in 2006, but the second issue was postponed due to personal issues and refunds were issued. Also in 2006, MetaFox announced ''[[Penguin Skiing]]'', ''[[Wacky Wonders]]'', and a ''[[Beats of Rage]]'' modification based on the animated television series ''Futurama''. As nothing was revealed after these announcements, all of these games are also considered to be on indefinite hold. ==External links== *[http://www.cyberdogcastle.com/ Cyberdog Castle website] *[http://dreamon.cyberdogcastle.com/ Dream On website] *[http://indiedreams.wikia.com/ Indie Dreams wiki] *[http://www.the-adventuress.com/ The Adventuress] *[http://jennifermcmurray.com/penguin/ Penguin translations] *[http://cydoca.com/wecmuseum/ WE Computers Museum] *[http://jennibee.itch.io itch.io game page] *[http://github.com/JenniBee github source code repository] *[http://jennifermcmurray.bandcamp.com/releases Bandcamp music page] *[https://www.deviantart.com/jennibee DeviantArt page] *[http://dcevolution.sourceforge.net/ DC Evolution] *[http://www.dreamcast-scene.com/ Dreamcast-Scene] [[Category:Programmers]] [[Category:Artists]] [[Category:Musicians]] [[Category:Website creators]] b3b448e7053e34fcaf12a8d451c88e1f8af4aed7 OneThirty8 0 1040 2241 2023-03-02T04:56:09Z Unknown user 0 Created page with "Josh Sutherland (also known as OneThirty8) resides in upstate NY where he sometimes still finds time to code software for the Dreamcast. Projects he has worked on include: *..." wikitext text/x-wiki Josh Sutherland (also known as OneThirty8) resides in upstate NY where he sometimes still finds time to code software for the Dreamcast. Projects he has worked on include: *[[VC/DC]], a VideoCD and MPEG stream player for Dreamcast (at the core, a port of mpeg2dec/libmpeg2 extended with mpglib added to handle mpeg audio) *[[sdlWolf]], a port of Wolfenstein3D *[http://www.storm-studios.net/onethirty8/YetiStuff.html a port of theYeti3D engine] using [[SDL]] for graphics *a [http://yeti3d-pvr.googlecode.com newer port of the Yeti3D engine] using the Dreamcast's 3D hardware for accelerated rendering. He has webpages at http://www.storm-studios.net/onethirty8 containing poorly-maintained news on several of his projects, binaries, and the (often messy) source code to most of his programs. He hopes you enjoy what he has created (or pieced together from the creations of others), and has even greater hopes that you don't expect too much from what he has made available. 000162b3de7fd0731ec738132095e076162802da Emulators on Dreamcast 0 108 2242 2022 2023-03-02T04:57:26Z Unknown user 0 /* Interpreters */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[SarienDC]] *[[ScummVM]] (Lucas Arts Adventures) c6caafb81cf48fa9c84464ddba12b8724c6a7074 File:Sarien.gif 6 1041 2243 2023-03-02T04:57:55Z Unknown user 0 wikitext text/x-wiki Sarien 48dfb66cdc5b9b6c7e80863c4d2c3b02f40ba4f1 SarienDC 0 1042 2244 2023-03-02T04:58:00Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=SarienDC| image=[[Image:Sarien.gif|240px| Sarien for DC]]| homepage=[http://www.ganksoft.com/products/product.asp?prod_id=sarien..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=SarienDC| image=[[Image:Sarien.gif|240px| Sarien for DC]]| homepage=[http://www.ganksoft.com/products/product.asp?prod_id=sariendc Homepage]| version=1.1| downloads=[http://www.ganksoft.com/redir.asp?target=sdcif Plainfiles]<br/>[http://www.ganksoft.com/redir.asp?target=sdcdj DiscJuggler]<br/>[http://www.ganksoft.com/redir.asp?target=sdcne Nero]<br/>[http://www.ganksoft.com/redir.asp?target=sdcsc Source]| release date=03/06/2002| author=[http://www.ganksoft.com/ Ganksoft]| original=[http://sarien.sourceforge.net/ Sarien]| systems=Sierra & <br/>Homebrew<br/>AGI Adventure| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=''Unknown| best=No,<br/>[[ScummVM]]| isactive=No| }} ==History== Sarien is a Sierra AGI resource interpreter engine that enables you to play early Sierra On-Line(tm) AGI version 2 and version 3 games, as well as AGI games written by other people. Sarien is covered by the Free Software Foundation's GNU Public License and is an open source development. Up to date information and anonymous CVS is available at http://sarien.sourceforge.net/. Please note that Ganksoft Entertainment has only created a port of Sarien to the Dreamcast. Please see the above link for more information on the base Sarien project. Sarien can play the following games (see the included "sarien.cfg" file for additional information). ===Supported Games=== * Black Cauldron (2.00) * Kings Quest 1 (2.0F) * Kings Quest 2 * Kings Quest 2 (2.2) * Kings Quest 3 (1.01) * Kings Quest 3 (2.00) * Kings Quest 3 (2.14) * Kings Quest 3 (2.14) * Leisure Suit Larry 1 (1.00) * Mixed Up Mother Goose * Mixed Up Mother Goose * Police Quest 1 (2.0A) * Police Quest 1 (2.0G) * Police Quest 1 (2.0G) * Space Quest 1 (1.0X) * Space Quest 1 (1.1A) * Space Quest 1 (2.2) * Space Quest 2 * Space Quest 2 (2.0A) * Space Quest 2 (2.0C) * Space Quest 2 (2.0F) * XMAS Card 1986 * Demo 1 * Demo 2 * Demo 3 * Demo 4 * Demo 5 * Kings Quest 4 (v2.0) * Kings Quest 4 (v2.2) * Black Cauldron * Black Cauldron * Kings Quest 4 demo * Manhunter New York (1.22) * Manhunter San Francisco (3.02) * Gold Rush (5.25) * Gold Rush (3.5) * Gold Rush (Cracked) (3.5) * Gold Rush (Cracked) (5.25) * Donald Duck's Playground ==Downloads== * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcif Plainfiles] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcdj DiscJuggler] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcne Nero] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcsc Source] - 03/06/2002 * 1.0 - [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcif10.zip Plainfiles] - 09/25/2001 * 1.0 - Nero: ''[http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcnet10.zip TAO], [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcned10.zip DAO]'' - 09/25/2001 * 1.0 - [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcdj10.zip DiscJuggler] - 09/25/2001 ==Links== * AGI fanmade games [http://forums.scummvm.org/viewtopic.php?t=3255 (download links)] ''via ScummVM forums.'' b4658fca7cf3620744caf8d150476ae9507587c8 2245 2244 2023-03-02T04:58:06Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SarienDC| image=[[File:Sarien.gif|240px| Sarien for DC]]| homepage=[http://www.ganksoft.com/products/product.asp?prod_id=sariendc Homepage]| version=1.1| downloads=[http://www.ganksoft.com/redir.asp?target=sdcif Plainfiles]<br/>[http://www.ganksoft.com/redir.asp?target=sdcdj DiscJuggler]<br/>[http://www.ganksoft.com/redir.asp?target=sdcne Nero]<br/>[http://www.ganksoft.com/redir.asp?target=sdcsc Source]| release date=03/06/2002| author=[http://www.ganksoft.com/ Ganksoft]| original=[http://sarien.sourceforge.net/ Sarien]| systems=Sierra & <br/>Homebrew<br/>AGI Adventure| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=''Unknown| best=No,<br/>[[ScummVM]]| isactive=No| }} ==History== Sarien is a Sierra AGI resource interpreter engine that enables you to play early Sierra On-Line(tm) AGI version 2 and version 3 games, as well as AGI games written by other people. Sarien is covered by the Free Software Foundation's GNU Public License and is an open source development. Up to date information and anonymous CVS is available at http://sarien.sourceforge.net/. Please note that Ganksoft Entertainment has only created a port of Sarien to the Dreamcast. Please see the above link for more information on the base Sarien project. Sarien can play the following games (see the included "sarien.cfg" file for additional information). ===Supported Games=== * Black Cauldron (2.00) * Kings Quest 1 (2.0F) * Kings Quest 2 * Kings Quest 2 (2.2) * Kings Quest 3 (1.01) * Kings Quest 3 (2.00) * Kings Quest 3 (2.14) * Kings Quest 3 (2.14) * Leisure Suit Larry 1 (1.00) * Mixed Up Mother Goose * Mixed Up Mother Goose * Police Quest 1 (2.0A) * Police Quest 1 (2.0G) * Police Quest 1 (2.0G) * Space Quest 1 (1.0X) * Space Quest 1 (1.1A) * Space Quest 1 (2.2) * Space Quest 2 * Space Quest 2 (2.0A) * Space Quest 2 (2.0C) * Space Quest 2 (2.0F) * XMAS Card 1986 * Demo 1 * Demo 2 * Demo 3 * Demo 4 * Demo 5 * Kings Quest 4 (v2.0) * Kings Quest 4 (v2.2) * Black Cauldron * Black Cauldron * Kings Quest 4 demo * Manhunter New York (1.22) * Manhunter San Francisco (3.02) * Gold Rush (5.25) * Gold Rush (3.5) * Gold Rush (Cracked) (3.5) * Gold Rush (Cracked) (5.25) * Donald Duck's Playground ==Downloads== * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcif Plainfiles] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcdj DiscJuggler] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcne Nero] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcsc Source] - 03/06/2002 * 1.0 - [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcif10.zip Plainfiles] - 09/25/2001 * 1.0 - Nero: ''[http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcnet10.zip TAO], [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcned10.zip DAO]'' - 09/25/2001 * 1.0 - [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/sdcdj10.zip DiscJuggler] - 09/25/2001 ==Links== * AGI fanmade games [http://forums.scummvm.org/viewtopic.php?t=3255 (download links)] ''via ScummVM forums.'' b7e8fc9242e9a34730c2b50db029daff45bb5674 SmashDC 0 1043 2246 2023-03-02T04:59:32Z Unknown user 0 Created page with "Developer: [http://mrsiggler.boob.co.uk/ MrSiggler] Version: 1.0 Last Updated: Thursday, May 9, 2002 Description: SmashTV style game. Submitted as an entry for the 200..." wikitext text/x-wiki Developer: [http://mrsiggler.boob.co.uk/ MrSiggler] Version: 1.0 Last Updated: Thursday, May 9, 2002 Description: SmashTV style game. Submitted as an entry for the 2002 programming contest. [http://www.dcemulation.org/files/software/smashdc1-nero.zip Nero image] [http://www.dcemulation.org/files/software/smashdc1-dj.zip DJ image] [http://www.dcemulation.org/files/software/smashdc1-plain.zip Plain files] b7a8b2d0b1f576ee753c8052d962c5153a09fb51 Cdi4dc 0 215 2247 631 2023-03-02T05:00:27Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=CDI4DC| image=[[Image:Cdi4dc 03b.gif|center|250px]]| homepage=[http://sbibuilder.shorturl.com/ Homepage]| version=0.3b| downloads=[http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_03b.zip Binary]| release date=4/13/2007| author=[[SiZiOUS]]| }} This program was created by [[SiZiOUS]] to replace [[bin2boot]] by [[Xeal]], a tool that converts ISO images into [[selfboot|selfbooting]] DiscJuggler images. It also supports other [[selfboot formats|selfbooting formats]]. There are Linux binaries based on 0.2b [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_02b_linux_colors.zip here] (colors) and [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_02b_linux.zip here] (no colors). =Older Versions= * [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_02b.zip 0.2b] - 7/13/06 * [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_01b.zip 0.1b] - 7/11/06 *[[:File:Cdi4dc 01b.zip|cdi4dc v0.1b by SiZiOUS]] *[[:File:Cdi4dc 02b.zip|cdi4dc v0.2b by SiZiOUS]] *[[:File:Cdi4dc 02b linux.zip|cdi4dc v0.2b for Linux by SiZiOUS]] *[[:File:Cdi4dc 02b linux colors.zip|cdi4dc v0.2b for Linux with colors by SiZiOUS]] *[[:File:Cdi4dc 03b.zip|cdi4dc v0.3b by SiZiOUS]] ff304075ef6a6597390072db5f740a60e8e0b1a2 File:Cdi4dc 03b img.gif 6 1044 2248 2023-03-02T05:01:07Z Unknown user 0 wikitext text/x-wiki Cdi4dc 03b 6b09c86b9ffb151a23fa44b97bce8524129aa166 Cdi4dc 0 215 2249 2247 2023-03-02T05:01:28Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=CDI4DC| image=[[File:Cdi4dc 03b img.gif|center|250px]]| homepage=[http://sbibuilder.shorturl.com/ Homepage]| version=0.3b| downloads=[http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_03b.zip Binary]| release date=4/13/2007| author=[[SiZiOUS]]| }} This program was created by [[SiZiOUS]] to replace [[bin2boot]] by [[Xeal]], a tool that converts ISO images into [[selfboot|selfbooting]] DiscJuggler images. It also supports other [[selfboot formats|selfbooting formats]]. There are Linux binaries based on 0.2b [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_02b_linux_colors.zip here] (colors) and [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_02b_linux.zip here] (no colors). =Older Versions= * [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_02b.zip 0.2b] - 7/13/06 * [http://dcemulation.org/1-newsdump/WindowsTools/cdi4dc_01b.zip 0.1b] - 7/11/06 *[[:File:Cdi4dc 01b.zip|cdi4dc v0.1b by SiZiOUS]] *[[:File:Cdi4dc 02b.zip|cdi4dc v0.2b by SiZiOUS]] *[[:File:Cdi4dc 02b linux.zip|cdi4dc v0.2b for Linux by SiZiOUS]] *[[:File:Cdi4dc 02b linux colors.zip|cdi4dc v0.2b for Linux with colors by SiZiOUS]] *[[:File:Cdi4dc 03b.zip|cdi4dc v0.3b by SiZiOUS]] 7eccee741c8bf1fc33201f7ac1dea614360a5e2a Dragyn 0 1045 2250 2023-03-02T05:05:09Z Unknown user 0 Created page with "Dragyn, also known as Adam Forster, was a Dreamcast developer. He released [[D.I.S.S.]], a JPEG Image Slideshow. His Website was hosted by B00B! Dreamcast Research and TheGy..." wikitext text/x-wiki Dragyn, also known as Adam Forster, was a Dreamcast developer. He released [[D.I.S.S.]], a JPEG Image Slideshow. His Website was hosted by B00B! Dreamcast Research and [[TheGypsy]] who actually hosts B00B!. It could be accessed at dragyn.boob.co.uk . His website got deleted in 2004 after Dragyn had been inactive since 2001. However, his website has been restored and put online again. It can be found [http://www.maturion.de/dreamcast/dragyn here]. 9f898414266324b822eab18f275c4c3cca718bd0 D.I.S.S. 0 1046 2251 2023-03-02T05:05:35Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=D.I.S.S.| image=no image| homepage=[http://www.maturion.de/dreamcast/dragyn Homepage]| version=0.8 beta| downloads= [http://www.maturion.d..." wikitext text/x-wiki {{Infobox_Dev_Information| name=D.I.S.S.| image=no image| homepage=[http://www.maturion.de/dreamcast/dragyn Homepage]| version=0.8 beta| downloads= [http://www.maturion.de/dreamcast/dragyn/diss/diss080.zip Plain Files]<br />[http://www.maturion.de/dreamcast/dragyn/diss/diss080dj.zip DiscJuggler]<br />[http://www.maturion.de/dreamcast/dragyn/diss/diss080-Nero.zip Nero]| release date=05/22/01| author=[[Dragyn]]| isactive=No }} D.I.S.S. ([[Dragyn]]'s Image SlideShow) is a JPEG slideshow application by [[Dragyn]]. The latest version was released on 22th May, 2001. '''Current Features (V 0.8 beta):''' *Decoding of JPG images only *Support for 24 bit color or Grayscale *Support for images up to 5120*3840 *Automatic scaling at fixed ratios of 1:1, 1:2, 1:4, 1:8 *Automatic centering of image *Next, Previous, First, Last, Blank Screen, and Quit commands *Images read from DISS CD or seperate JPG images CD (from /images/ dir) cd2b11e6a0fd73f49f3ca35e2a2a29880e1ecc1f Othello 0 1047 2252 2023-03-02T05:05:58Z Unknown user 0 Created page with "An Othello game. http://www.dcemulation.com/dl/dl.php3?url=files/software/Othello-DJ-img.zip" wikitext text/x-wiki An Othello game. http://www.dcemulation.com/dl/dl.php3?url=files/software/Othello-DJ-img.zip 0a17f327204470e3e3f85d766a6be4bc6a912712 Chui 0 925 2253 2090 2023-03-02T05:07:40Z Unknown user 0 wikitext text/x-wiki Chui is a Spanish Dreamcast developer. He did a lot of projects and he is very well known for maintaining the Dreamcast port of [[SDL]] and OpenGL. He is working on a remake of Return to Castle Wolfenstein for Dreamcast and he is also porting the well known game development library Allegro to the Dreamcast. *[[NEO4ALL]] - Alternative open source NEOGEO/CD emulator. *[[AES4ALL]] - NEO4ALL fork for emulating home and arcade NEOGEO systems. *[[DCASTAWAY]] - The first Atari ST emulator. *[[UAE4ALL]] - Open source Amiga500 emulator. *[[SNES4ALL]] - Alternative Snes9x port (Super Nintendo emulator). *[[ZX4ALL]] - Open source ZX-Spectrum emulator. *[[MAME4ALL]] - MAME GP2X adaptation for Dreamcast. *[[PSX4ALL]] - Open source Playstation emulator. *[[NOIZ2SA]] - Abstract shoot'em up. *[[FENIX]] - The way to game development. *[[SDL]]+OpenGL : Dreamcast SDL and OpenGL. ==Weblinks== *[[http://chui.dcemu.co.uk/ Chui's Homepage]] *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=28344 Chui's profile on DCEmulation] This interview with [[Chui]] was taken by [[Maturion]] in February 2008. '''What is your current Dreamcast project that you are mainly working on?''' During last year i have worked on: *New FAZE Z80 assembler core for ZX4ALL, MAME4ALL and NEO4ALL emulators. *DCaSTaway emulator was adapted to FAME M68K core, so now it is more stable and more fast. *A new and secret emulator project by Fox and me. *ZX4ALL emulator was released with a lot of enhanced features. *First alpha release of Neverball game. *KGLX library continued for getting a new OpenGL implementation for KallistiOS. *DreamEDGE (EDGE) and DreamPlaces (DarkPlaces) 3D engines port using new KGLX library. In general, 2007 was not a very productive year for me because my son was born and he needs a lot of my free time, but i love playing with him. Also i hope release a beta non-playable of Fusion game (DreamEdge based) and other for RetroMadrid/MadriDC 2008 party (8th March): *http://3dfxdev.blogspot.com *http://www.retromadrid.es '''When did you start developing Dreamcast software and why did you do that? I started to coding for Dreamcast around 2003 summer with a simple SDL port, [http://sdl-gp32.sourceforge.net/dcircus.html DCIRCUS]. At this time, i was porting SDL for GP32, but Fox persuaded me for continuing FAME M68K core for Dreamcast and Ron for porting Castaway (an Atari-ST computer emulator). Then i was falling in love, this machine is wonderful. But i always have seen to Dreamcast a good platform for emulators because it is enought powerfull and cheap for playing old games on a TV. There are not a lot of people coding for Dreamcast now, i think that there are a lot of things to do yet. '''Some time ago an unknown programmer from Germany has made a basic Dreamcast port of DaedalusPSP ([[DaedalusDC]], a Nintendo64 emulator. Sadly, he won't continue his work on this emulator. Do you think anybody will continue his work? Will this emulator ever allow to play games in a playable speed?''' I think that it is not easy that another coder continues that work because it is a hard task and it is possible that never runs for playing decent way. Maybe i will continue it at far future, now i have a lot of running projects, but i always have wanted to try it after [[PSX4ALL]]. '''What do you recommend coders who want to start out with Dreamcast programming?''' I recommend writing SDL portable code as far as possible. Because it is more easy and confortable work for your PC, like running a simple test or debugging and tracing a bug. '''Did you work with any other consoles or handhelds than the Dreamcast?''' Mainly i have worked for GP32 console, porting SDL libraries and [[Fenix]] gaming runtime. I love this handheld console but there are a lot of people that write code for it (now for GP2X), so it is not necesary my contribution now. '''Will you release a new version of [[SDL]] for the Dreamcast?''' I planned to release this year using newest [[SDL]] version and a bit changes. But really SDL for Dreamcast is very complete and stable now. Anyway, KGLX will be a good complement, i think that a lot of 3D games could be ported, like Neverball. '''What are your wishes for the Dreamcast scene in 2008?''' I wish for have a lot of time for doing ports and games for Dreamcast. And i encourage all scene for not falling in lazyness, there are a lot of work to do and it is very funny. '''Do you think the Dreamcast will still see some new releases after 2008?''' Why not? I would like continue coding for it, it is my hobby and i want not change it as developing target. I see now new releses for ZX-Spectrum computer, it is a very old machine with a decent scene. '''Do you think SEGA will ever make a new console?''' I really do not know but maybe it is not important because SEGA is not dead and continues doing fantastic games. Always i was a Nintendo fan and it is perfect play SEGA games with a DS or Wii. ff0ef1dd8463d3d7bc0574f20df81743d10cbccc DCFighting 0 1048 2254 2023-03-02T05:08:00Z Unknown user 0 Created page with "Developer: [http://jimbomania.com Jimbo] Version: 0.3.1 Last Updated: May 20, 2002 Description: A 3D fighting game for the Dreamcast. [http://www.dcemulation.org/files..." wikitext text/x-wiki Developer: [http://jimbomania.com Jimbo] Version: 0.3.1 Last Updated: May 20, 2002 Description: A 3D fighting game for the Dreamcast. [http://www.dcemulation.org/files/software/dcfg031Nero.zip Nero Image] [http://www.dcemulation.org/files/software/dcfg031DJ.zip Disc Juggler] [http://www.dcemulation.org/files/software/dcfighting031.bin Plain Files] and an outdated version download: http://www.dcemulation.org/dl/dl.php3?url=files/software/dcfg022.zip e318fd01cea620ac9bd125c18171135bb0a1b0de Strat76 0 1049 2255 2023-03-02T05:08:16Z Unknown user 0 Created page with "Start76 was a Dreamcast developer of the early days. He released [[DCMP3]]. *[http://www.maturion.de/dreamcast/dcmp3 Archived version of his DCMP3 homepage]" wikitext text/x-wiki Start76 was a Dreamcast developer of the early days. He released [[DCMP3]]. *[http://www.maturion.de/dreamcast/dcmp3 Archived version of his DCMP3 homepage] abe73654420be045e92899b9df74c9c26f35f203 File:Neverball.jpg 6 1050 2256 2023-03-02T05:08:50Z Unknown user 0 wikitext text/x-wiki Neverball 1cebf1f67c8d1b47f274b000ac7baf1389c06fc8 Template:Infobox Ports Information 10 1051 2257 2023-03-02T05:09:12Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|<i>No Screenshot Available</i>}}} |- style="background:#ffffff" |Homepage || {{{homepage|<i>Unknown</i>}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|<i>Unknown</i>}}} |- style="background:#ffffff" |Based on || {{{original|<i>Unknown</i>}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|<i>Unknown</i>}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} 028dea6e121ab898f2b79597cb3c55cac3bffaef Neverball 0 1052 2258 2023-03-02T05:09:18Z Unknown user 0 Created page with "{{Infobox_Ports_Information| name=Neverball| image=[[Image:neverball.jpg|center|250px]]| homepage=[http://chui.dcemu.co.uk Homepage]| version=1.0| downloads=[http://www.m..." wikitext text/x-wiki {{Infobox_Ports_Information| name=Neverball| image=[[Image:neverball.jpg|center|250px]]| homepage=[http://chui.dcemu.co.uk Homepage]| version=1.0| downloads=[http://www.maturion.de/dreamcast/dateien/spiele/neverball-beta.rar DiscJuggler image]| release date=3/8/2008| author=[[Chui]]| original=[http://www.neverball.org Neverball]| best=Yes| refreshrate=60Hz| isactive=No }} Neverball is a very good looking Super Monkey Ball clone. It was ported to the Dreamcast by [[Chui]] and uses his port of [[SDL]] and OpenGL. [[Category:Homebrew game]] 05dd3886d52c99626ab8a42bf20ff7816e3168dc Sin 0 1053 2259 2023-03-02T05:10:27Z Unknown user 0 Created page with "Sin, also known as Jamin Vander Berg, was a Dutch Dreamcast developer. He released [[Sintendo]], one of the first emulators for the Dreamcast. His [http://sintendo.dcemulation..." wikitext text/x-wiki Sin, also known as Jamin Vander Berg, was a Dutch Dreamcast developer. He released [[Sintendo]], one of the first emulators for the Dreamcast. His [http://sintendo.dcemulation.com/ website] was first hosted by DCWarez.com and then hosted by DCEmulation. An interview with him can be found [[Interviews:Sin|here]]. Below is one of the last posts he made in his [http://pub21.ezboard.com/bdcsnes own forum]. His last post there was on 22th January 2003 responding to someone who had replied to this message. He has never been active again in any Dreamcast forum. The original topic can be found [http://web.petabox.bibalex.org/web/20041217131810/p210.ezboard.com/fdcsnesdcsnes.showMessage?topicID=99.topic here]. ''It has been a great deal of time since I have updated this website, reviewed the posts here, or even touched the code for [[Sintendo]].'' ''In recent ponderings, I have wondered if what I have done is worth working further forward towards. While I am deeply satisfied with how far everything has come (some may not agree, but I doubt they are programmers), I still never got it as far as I had hoped.'' ---- ''The Dreamcast is all but a dead system. Many of us still use ours, I pop a disc in and play from time to time, but all of the effort I've put into [[Sintendo]] in the past, while not wasted, may fall on deaf ears if I continue to pursue the project, so long after the consoles unfortunate demise.'' ''Work, as always, is a burden on a creative programmer's time and imagination. I'll not use that as an excuse for anything. I still program from time to time, but its been quite a while since I've approached anything that compares with the scope of [[Sintendo]].'' ''Never before or since have I conceived a project with such determination to see it through to even as close a level of completion. Anyone who programs (and some who don't) should understand the year plus of plight that went into this project. I appreciate all of the support I have received over this time. I gratefully appreciate my host, dcemulation.com, for keeping this site up more than a year after a single update.'' ''I am by no means saying that Sintendo is a dead project. I am not quitting, per se. I am only trying to tell all of you, what few dedicated followers I may have left, that I have not worked on it for quite some time, and can't necessarily forsee any time in the future when I will. I can not even promise that [[Sintendo]] *will* ever be worked on (by me at least), but I'd like to think that that's not the case.'' ''I have been dedicated to games programming since the age of 15. Now, 25, I still work towards the same goal. [[Sintendo]] bore me priceless experience in the console programming market that I will take with me in the future. Where it will lead? I can't say for certain. I'd like to develop games for many years to come. Personally, and most importantly, I'd like to develop a game to completion. Perhaps we may some day see [[Sintendo]] on another console (although I currently own none to port it to). Time will tell.'' ''Thank you all again for all the support I've received. I apologize for lack of adequete postings as well as lack of decisiveness.'' ''Until another time,'' ''Sin'' This is an interview with [[Sin]], the creator of [[Sintendo]]. It was taken in late 2001 by Emulation-X of GeoShock, a popular emulation site in these days. GeoShock went offline in early 2006, so we have published this interview here. '''Emulation-X: Why did you make Sintendo?''' ''Sin: I made Sintendo because I wanted to be able to play Super Nintendo games on my Dreamcast. I released Sintendo to the world because I imagined other people would like to as well. There wasonce a time when such a thing was only imaginable and I saw that I *could* do it... I used Snes9x because it is portable, maybe the development a lot easier The only other really useful SNES emulator is ZSNES, which may be better in some ways, but is farfrom portable. ZSNES is written primarily in x86 assembly, everything written in that way must be re-written to work on the Dreamcast. Snes9x was just a much more attractive option because it's written in C.I have had to do very little re-writing of the Snes9x code. I started most of my research on the forums of the "warez" sites. Dcisos.com had a development forum The portable version of Snes9x has a file called how2port.txt. Its like following instructions, kind of It's quite a bit more complicated than that. '''Emulation-X: Who made the a big Impact with you while making Sintendo?''' ''Sin: I'd have to say Gary, the author of Snes9x had a huge impact on me. The fact that he responded to my email suprised me, and while he hasn't given me any particular help... He has been very supportive...as well as creating the thing in the first place. [[Tubooboo]] has helped me solve a few of my most frustrating problems. [[Tubooboo]]'s presence on the scene was also a great motivating force i wish a great deal of success to him with his project. '''Emulation-X: [[Tubooboo]] also has a Snes Emulator for the Dreamcast. Was this a race?''' ''Sin: The fact that he started it, however, spurred a great deal of competitiveness in me that was probably the direct cause of [[Sintendo]] being released on time there was probably an unspoken race between us. the race ended when Marcus won, by a half a day I released my emulator later that day, and then an improved version the next. It has sound and saving, two great feats,but I understand that the sound slows down the emulation somewhat and speed in controlled by a frameskip, which takes away some of the smoothness from the games. '''EMULATION-X: When did you get involved in Emulation?''' ''Sin: I don't know when really maybe around Nesticle. It ran on our P100 at good speed, it was fun to play all those old games even my mom loved it. Then emulators started coming out that emulated the SNES following in a loose sense of the term. I've used a lot of them,I've even considered doing SNES emulation myself. I had a few ideas but never the time to research all the ins and outs the SNES is a very complicated machine. I used to imagine that compiling a SNES cartridge into machine code would speed emulation a great deal...and it probably would...it is unfortunately not very practical . '''EMULATION-X: Besides making Sintendo (Snes for DC) are there any other Emulators that you might want to port in the future to the Dreamcast?''' ''Sin: I don't have any intention on porting another emulator to the DC. Though SNES emulation on the PS2 would be very cool...and certainly be less problematic that my orignal port I haven't exactly decided yet. I am a games programmer at heart. I love RPGs in specific and I can't play one without analysing it a great deal I've been programming rudementary RPGs since I first started programming and it is perhaps the reason I began programming in the first place.So I guess there's a good chance that may be my next route '''Emulation-X: What other Emus do you use besides Snes9x?''' ''Sin: I kind of like Pokemon, so sometimes I use the no$gb emulator, or whatever on the PC version you can run more than one gameboy...which makes trading useful, and I programmed a small app that switches the save files arround so I can play more than one save... and if I click one check box, I can trade without actually losing the pokemon I traded (i.e. Copy a Pokemon) '''EMULATION-X: What is your View on Utopia boot disk (DC-warez) and the hole shut down of the DC news web sites?''' ''Sin: The boot disk is a good thing, and I don't believe it is really illegal. News sites are news sites, and Sega has no right to shut them down for providing information regardless of the nature of that information '''EMULATION-X: Has Sega or Nintendo never tried to contact you ?''' ''Sin: No, but I have considered contacting them. Perhaps obtain a license for [[Sintendo]]... or get a job :) or licensing for future projects like the aforementioned RPG its an option i am looking into I'd imagine the people that use it for emulation will be using it for some time to come '''Emulation-X: What do you think about the Dreamcast Now?''' ''Sin: As a consumer system, it's closed to dead. No one really wants to spend any money on it any more the games have been released (illegally) for free. '''EMULATION-X: Do you think that Emulation and Warez kills a system?''' ''Sin: Yes and no. Warez killed a lot of profits Sega and its developers could have made. But then all those kids bought tons of accessories because they had extra money. Emulation is a program I don't think in and of itself emulation and emulators for the Dreamcast could kill the system But then, it's kindof like cheating at a game... You played it for a while and you're bored... so you want something new... So you cheat to make it more exciting... eventually (maybe sooner, maybe later) thats gets old too... but the game was already old in the first place if you catch my analogy, but I know I'll stick pick up my Dreamcast for years to come and play some old SNES games . '''EMULATION-X: Where did the name Sintendo come from?''' ''Sin: spankthemonkey, my web designer, thought of it. '''EMULATION-X: Do you plan on improving on [[Sintendo]] anytime soon?''' ''Sin: I'm still improving [[Sintendo]] almost every day there's a lot that still has to be done speed is an issue, no one wants to play a game (at least not for a great deal of time) if it's slow, saving should be implemented soon and I really want to be able to hear the music for ChronoTrigger while I'm playing. There are a few details that were left out from my first release I am covering those bases (and maybe throwing in a few extras) and I'll release in under a week. '''EMULATION-X: What type of ideas might you add to the Menu system?''' ''Sin: An in-game menu has already been done (but still a little buggy) I have to fix it so it shows the last file and so it doesn't crash if you don't have enough files then I may add the ability to browse folders, both to improve the organization, and to add to the maximum number of ROMs per CD. '''EMULATION-X: Right now the maximum is 128?''' ''Sin: Well, technically 127 :) but yes..... with folders, each folder will be able to have up to 128 files so the number of ROMs possible is nearly infinite (up to the storage capacity of a CD) other than that, I'm trying to add a small speed increase. '''EMULATION-X: Thank you Sin for taking the time to answer all of My Questions, I really hope that anyone that reads this can understand what dedication you have and that this is only your hobby and you don't get paid to do this.''' ''Sin: Well, thank you for taking the time to interview little old me :) I hope Everyone will enjoy emulation on the Dreamcast :) 7ceb6edef2882f8c0220c2f8bbd63c32b8c9bc5f DCGrendel 0 1054 2260 2023-03-02T05:12:41Z Unknown user 0 Created page with "==DCGrendel== DCGrendel was a Dreamcast programmer from Belgium. He released three binary loaders for the Dreamcast, [[Demo Menu]], [[DCHakker]], and [[DreamInducer]]. He a..." wikitext text/x-wiki ==DCGrendel== DCGrendel was a Dreamcast programmer from Belgium. He released three binary loaders for the Dreamcast, [[Demo Menu]], [[DCHakker]], and [[DreamInducer]]. He also released an Apple ][ emulator called [[Apple II Soul Captor]]. Like many other Dreamcast developers, he was also active in the Xbox scene and he released his Apple ][ emulator for the Xbox, too. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=5157 DCGrendel's profile on DCEmulation] *[http://archives.dcemulation.org/dcgrendel/ DCGrendel's website] afb0aae5305f73cba74eebf403da0252b3dae5c7 Cryptic Allusion 0 1055 2261 2023-03-02T05:15:33Z Unknown user 0 Created page with "Cryptic Allusion is a software development group led by Dan Potter that has written several games and demos for the Dreamcast, including a commercially-sold game (''Feet of..." wikitext text/x-wiki Cryptic Allusion is a software development group led by Dan Potter that has written several games and demos for the Dreamcast, including a commercially-sold game (''[[Feet of Fury]]'') and the most successful and widely-used homebrew software kit ''[[KallistiOS]]''. Dan Potter also developed [[libdream]], the first free development library for the Dreamcast. At the moment they are working on a Jump'n Run game called [[Donk: Samurai Duck]] ==September 2001 Interview with Dan Potter== This an interview with Dan Potter from [http://www.boob.co.uk B00B! Dreamcast Research]. It was taken on the 27th September, 2001 by Wraggster and was edited by [[TheGypsy]]. '''B00B! Dreamcast Research: Can you tell us where were you born, where you live, your family details, etc.?''' Dan Potter: I was born in Dallas, TX and lived there for 16 years until I moved out for college in Denton (also TX) and then Austin (again, TX). My dad's a geek of sorts himself, working as a machinist for engineers at design shops, and occasionally doing a bit of design work himself. His hobby now is making wind chimes and selling them at various weekend markets =). He's probably responsible in large part for me getting into computers and technology at all, I've got two older sisters who harrass me incessantly about how much of a geek I am. In a good natured way of course =). My step-mom's always asking when I'll strike it rich in my game development work so they can retire to Colorado but I suppose for the near future I'll have to keep saying "soon", hehe =) I have lived in Austin, TX since 1996, where I've been going to college. I recently lived in Tucson, AZ for 9 months and will move back there once I finish my degree. Can't beat the scenery, hiking/biking, amazingly dark sky for astronomy geeks, etc... just a great place. I guess Jessica (the girlfriend) moving back there helps to make that decision as well =) '''B00B: What qualifications do you have? What made you get into computers?''' DP: I'm kind of combining these two because they're quite related. Hmm... where do I start? (I did warn you about that head inflation thing ^_^;). When I was 4 years old, my father brought home a Speak and Spell from TI (where he was working at the time). Employee store, good discounts, etc. I think from that moment on it was too late for me to get interested in anything else for quite a while =). I got a TI-99/4A home computer when was 5 or so, and it grew from the simple console with Basic and Logo to a home computer workstation (lol). Basic console had extra RAM and a speech synth hacked into it, new cooler power supply, expansion box with a persistent RAM disk, two floppy drives, all those goodies! =D On that thing I learned 9900 assembly, and we bought a PC not too long after that. I guess it went from there: I spent most of my waking hours at school or on the computer. I wrote a tracker called "Farandole Composer" which some of you may remember with curses =). I participated somewhat as a side in the PC demo scene of the time, but we never really made much in the way of demos, and did a lot of talking. =\ Ah well, I got a few friends from that time. I had a BBS called Programmer's Oasis (it was 214-328-6142, if anyone remembers better by that =). I participated in a competition programming team in high school. It was a geeky high school (Science/Engineering Magnet) so we were like the football stars of the school. That was pretty damned cool, for a change =). I left there after two years to go to the Texas Academy of Math and Science, in Denton, where they shut you in a dorm with 399 other smart (and mischeivious) people for two years... man was that a riot! =) I got my high school diploma and two years of college there and moved to Austin, to finish a CS degree at UT. I'm still trying, but I've almost got it =). I'll stop there before I bore everyone, but suffice to say I've been sitting in front of a keyboard for a large part of my life since 5, and I'm 23 now. I've got a strong interest (probably thanks to school) in understanding computational science and how things _should_ work rather than just getting them working, but just kicking back and coding is quite enjoyable as well =) '''B00B: What projects/coding have you done previous to any Dreamcast programming? ''' DP: I listed a few above, but of interest to the DC community are of course the demos; I also worked on several (abortive) game project attempts with a friend of mine from Science/Engineering (hi Matt! =). These started with a simple overhead tile map and progressed over the years to a full Quake-style engine with source lighting and a custom scripting engine. Also of trivia value is that [[KallistiOS]]/DC was not the first incarnation of [[KallistiOS]]. Most people probably don't know this =). KOS was originally a project for the PC. I had a book called "Advanced 386 Programming" (I think that was it) that introduced me to protected mode, multitasking, etc. I had to sit down and write one =). I did all of that from that book and manuals I found on the net, so it proves you don't need a bunch of official devkit materials nor a degree to do this sort of thing. Just a keen interest and a lot of determination. '''B00B: What made you get into Dreamcast Development?.''' DP: It was almost an accident, quite literally. My roomate Phil invited us over to play Soul Calibur a long time ago, and I was so floored by the amazingness of that game (and obviously the system underneath it) that I added it to near the top of my "acquire when money arrives" list =). Soon after I bought the DC, they sent me an image for the CDX. Now, this was fantastic because I could play imports and all of that, but it got the gears turning in my head: if I can burn a normal CDR and run it on the DC with THEIR code, why not replace the code and burn my own anyway? I started hacking on the CDX and eventually found Marcus Comstedt's site. I didn't have a "[[Coder's cable]]" at the time so Tursi helped me out by running my test program and sending a screen shot. I got on the mailing list and started being more active with it, and a few weeks later I couldn't stand the suspense any longer: me and Jordan ordered the parts and built two cables, and I bought a SCSI CD-R to burn DC CDs with (since the one at work didn't do the job). Tursi and I worked on what was to become [[libdream]] for a little while, and eventually that did morph into [[libdream]]. I later got to discussing the idea with Jordan of writing a real embedded OS for the DC, and that was when [[KallistiOS]]/DC was born. It shares the name and some of the concepts of the original KOS/i386 but none of the code. Things just kind of went from there. '''B00B: Was [[Ghetto Pong]] a good learning step onto bigger things and how complex was it to code and get running nicely?''' DP: Oh yeah. [[Ghetto Pong]9 was Jordan's baby actually. He wanted to write a Pong clone for the DC just to play around with the coding aspects of it, so the original Ghetto Pong was actually just a red square moving across the screen with green block paddles. That's why it's "Ghetto"! =D I took that work of his and added menus, background music (thanks El Mobo! =), and sound effects, and his brother Kyle added some graphics. The result is the Ghetto Pong you see today. '''B00B: How did you start and what programs did you use to start coding?'' DP: I think I managed to answer this above during my lengthy discussion of my start with computing =). I'll add to it, though, that I used: * TI Basic, then * TI Logo, then * TI Extended Basic, then * TI 9900 assembler, then * GW Basic, then * Power Basic, then * Turbo Pascal for DOS, then * Turbo C for DOS, then * Watcom C for DOS, then * GCC for Linux That pretty much brings it up to modern =). I've had stints with Haskell, Python, Scheme, and a number of others that I don't use for "mainstream" work now. '''B00B: Tell us about your [[KallistiOS]] and [[libdream]] projects and did you have any idea that your work is looked on as the most significant piece of hobbyist software on the Dreamcast?''' DP: I guess I'll give an anecdote about [[KallistiOS]] that is kind of amusing, which I've talked about previously only in a translated Spanish interview. When we started KOS, we were trying to decide on a name. The original suggestion was actually "HuevOS", believe it or not. Our mascot was an egg, wearing a sombrero, and riding a surf board! (just consider all the puns for a minute =). Eventually, though, [[KallistiOS]] was chosen as the name because of the high interest among the authors in Discordianism =) I didn't know that it would eventually be looked upon as one of the most significant pieces of hobbyist software, when I started (or rather, when we started =). I guess it started the same way as any free software / open source project: there was a need to be filled, I wanted it filled, and I worked towards doing so. I guess the DC is complex enough that once there was a base and someone was working hard on it, no one else wanted to take the effort. The exceptions I know of are great work too, but they seem not to have caught on very much. I guess to me it became "truly significant" when I realized that people high up inside Sega were looking at it for more than a glance. =) Not for usage in anything official, just that they had added it to their map. Everyone on the dcdev list is probably familiar with this story though. '''B00B: What plans for the future do you have for KOS and KosWin?''' DP: I'll answer the second first since it's easiest =). I don't have any plans for KosWin because it was just something I did on a whim to try to help out some people who were having troubles. It seems on retrospect that the idea was well placed, but I'm kind of a fish out of water in the Windows world. ^_^; So I'm hoping other people will pick up the idea and go with it, and it seems that is happening. I'll be happy to host a good one on SourceForge's behalf (HEH). For KOS itself, I am basically hoping that it will grow to fill every need for hobbyists that was filled by Katana for official developers. This sounds a bit presumptuous, but I feel like we're already there to a large degree. I can't name any names, but a developer at SEGA told me once that my tools were easier to use than theirs for some things! With the addition of [[KGL]], an unencumbered MP3 player (working on it =), and the re-integration of things like lwIP and OS mode, it could go just about anywhere. I guess we'll just see what happens. '''B00B: What programs have helped you on the Dreamcast and how significant is a hardware OpenGL driver and to what programs/emus would be made accessible with it?''' DP: I guess as far as what _programs_ have helped, the major one has been dc-load and dc-load-ip. [[Marcus Comstedt]]'s tools have always come out as a sort of first pass to get people going, and then Andrew's tools come out and perfect the process. That has really helped things along. On the hardware OpenGL driver, be careful on terminology here. I'll be quick to point out (and so would SGI's lawyers! =) that what we have isn't an OpenGL implementation, but an OpenGL-like library. This is an important distinction, because I want to make GL programmers feel at home (and have something easier than raw TA for myself!). But it's not really OpenGL. I think the GL driver, though, is VERY significant. I didn't realize until I started using it myself just how convienent it is. With a few more mapping modes (e.g., ortho) and some glu functions, it could easily cut development time for DC things in half or more. I've definitely become a believer of GL at this point =) What could be made with it? Your imagination's the limit!(tm) Once lwIP gets re-integrated (and I've potentially got some SMB code coming from someone else) you could spend an afternoon writing an MP3 jukebox with fantastic visualizations. Games, demos, and even emulators. Who knows. The same things are possible that were before, they are just much easier. On emulators, I don't really know. I guess it's up to the emulator authors to be ingenious enough to use the 3D at all. This is not a simple problem since most earlier systems assume very low level control over the output (like SNES's HDMA). '''B00B: What programs/apps/emus would you most like to see come out on the Dreamcast?''' DP: I'm looking forward to JamDu coming out, if for no other reason than to see what came of that late-night inspiration almost a year ago =). Something else I always thought would be pretty nifty is a Dreamcast tracker. Why not?? You've got 64 channels of wave table sound, hardware accelerated 3D for any sort of inteface you want, a keyboard, a mouse, and space to save files (BBA, mainly). Even though Farandole was my last, I have still maintained an interest in trackers. Emulators.. I'd like to see a SNES emulator finished with full frame rate and sound quality. I'd love to pull out some old classic games and play them on a console again, since the original machines tend to decay and break over time. Beyond that, I'm always interested to see demos and games. Delicious was a very cool surprise that I've shown all my friends to say "here, this sort of thing is why I've been slaving over this box!" =) '''B00B: What's your opinion of the new super consoles like Xbox, Gamecube, Game Boy Advance, and the Playstation 2?''' DP: Oh man. You could fill a whole interview with this. =) But I'll refrain since I've got to run to class in about 15 minutes. *'''Xbox:''' Microsoft owns it, they're gonna do it wrong. I've seen some things on this machine that look VERY cool, like Jet Set Radio Future, and Dead or Alive 3. I've heard that the Microsoft titles are really looking up too, but the ones I saw at E3 were pretty disappointing. Guess time will tell. One thing I will say, it's HUGE. Way too big. For that reason alone it will probably fail in Japan. *'''Gamecube:''' Looks nifty, well put together, solid company behind it as usual. This will be a "safe" console to get for some fun games. The Star Wars game looked outstanding (again, at E3) but most of the others were not so super looking. Again, I guess time will tell. Integration with the GBA will definitely help the 'cube. *'''GBA:''' High on the cool factor, and it's great to have a real console to play a lot of old games being ported up. I'm guessing this thing hasn't even remotely been fully tapped for potential, and it's already got some amazing 3D-looking titles (like that tunnel game, can't remember the name now!), a DivX player (slow, but it's there), etc. *'''PS2:''' This is a really great machine processing power wise, but Sony has made the same mistake that they killed Sega for on the Saturn: the box has amazing processing capabilities, but it's extremely hard to code for. I don't even want to think about what they had to do to that thing to get GT3 out of it =). And I have to comment on one other aspect that always irritated me about it: whole lotta hype, normal amount of substance. Sony's PS2 marketing probably killed the DC, even though the majority of the released games for DC are far superior in game play and enjoyability to the PS2 titles out. This may change over time but I'm not keeping my hopes up. '''B00B: Which console looks the best for dev'ing on?''' DP: Still the DC. Except of course that your audience is quickly waning. I'd say next in line behind that are GBA and probably Xbox (it's a PC, it can't be that hard to get into =). Last I heard PS2 is still a major pain to dev for but this may improve in the near future. '''B00B: What are your favourite games for every system you have owned?''' DP: Ahh, well this one is easy! I've only owned two systems -- PS1 and DC. For PS1 I've like a lot of games on it, but I'd have to say one of the "good but unknown" titles is N2O. If you haven't played it, do so. It's cheap, and it's like concentrated Crystal Method (the band) stuffed into a game =) For DC, I basically haven't disliked any of the games =). They are almost all fantastic, at least the major ones. I've had a lot of fun with Evolution (3D Nethack, I like to call it), and a lot of team play fun with Phantasy Star. '''B00B: Your thoughts on the Dreamcast Emulation/Development Scene and how can it be improved?''' DP: I've probably said enough above already, but the one thing that could really help the scene is the one thing that's never gonna happen now: continued support for the hardware. I had glittery dreams of a hobbyist section in ODCM (which is now dead), some sort of hobbyist area on Sega's DC site (slowly dieing), who knows. That whole dialogue with John on the dcdev list was very promising. Suddenly, overnight, it became the "console that could have been". A truly regrettable state of affairs, but I guess a company's gotta do what it's gotta do to stay alive. At least Sega has continued making games! Their games have almost always been trend setters and it's good to see they will continue to be. See here, Tecmo already has a Space Channel 5 clone =). Anyway, I digress... '''B00B: Thank you for your time; it has been a honour for the scene.''' - wraggster ==2004 Interview with Dan Potter== This interview with [[Dan Potter]] was taken by [[MetaFox]] for the DreamOn magazine #1, which was released at the Midwest Gaming Classic in 2004. '''How did Cryptic Allusion begin?''' To start all the way at the beginning, I was going to do some web consulting for a company I was interning with for the summer in Dallas, TX. They advised me that tax-wise, I'd probably end up doing best if I formed a company to do the consulting through. My task then was to come up with a unique name that someone else wouldn't have already taken, and Cryptic Allusion was it. I'm still not 100% sure where those specific words came from, but that's what I came up with. Cryptic Allusion didn't do any more web consulting after that, and in fact it didn't do much of anything business related for a long time. It sort of morphed into a label for me plus any current group of friends that were working on something interesting. The membership of that group fluctuated over the years. During my years at the University of Texas, I was approached by a group of starry eyed game industry hopefuls trying to draft me into their game making effort. This included a number of people who are some of my best friends now, including Roddy. The original plan was to do a shooter type game for the PS2 (not quite out yet, at that time) and move on from there to an RPG project. We would get some basic stuff worked out and then hunt for funding, which was a pretty sound idea back in those days. The long and short of it is that after a very exciting start, the group more or less melted away. But I was too obsessed with the idea of starting a game company at that point, being as how it had also been my goal (little did they know) since I was about 6 years old. When I started getting into DC homebrew, I saw an opportunity arise for such a project. I emailed up Roddy and said: How would you like to work on this DC project? I probably can't pay you right now, but it might be a good way to get yourself out there. He responded back saying that he'd pay ME to work on a project, any project. Apparently Roddy felt the same way about all this game stuff. Our goal was to produce Tryptonite, the originally planned shooter game, for E3 and pass it out there as a way to get started. For various reasons we had some organizational and communication issues between ourselves and third party guys we'd pulled in to do parts of the game, so it was morphed into DC Tonic by executive decision about a month before E3. This turned out to be a good deal, as I believe DC Tonic still stands as one of the cornerstones of the DC homebrew scene's accomplishments. It also (along with some contacts of one of our members) got us into the invite-only Sega booth (score!) I'll continue this below in question 2... '''How did the idea for Feet of Fury materialize?''' After E3 we were sort of basking in the glow of the press and industry attention we'd attained with DC Tonic. We had also been infected by Dance Dance Revolution at A-Kon shortly after E3 (I use the word "infected" here because it's the most accurate -- once you catch DDR, you feel the compulsion to play day and night until it's out of your system a few years later). Roddy's a musician who makes some good dance/techno. The wheels started turning -- maybe there's some way we could put Roddy's music into DDR. I said, hey, I've got this nifty DC homebrew stuff sitting here, why don't I see what I can whip up? Well, the momentum generated there was a lot more than we expected. We were playing DDR and talking about the possibilities of making our own and such, and someone (can't remember who, might have been me) said, why should we make a DDR clone? Why don't we go way beyond DDR and make the game into something new and interesting instead of the same-old-same-old? We'd also been playing a real load of Puzzle Fighter, so the obvious idea was to combine the two and allow players to "attack" by throwing "arrow bombs" to the opponent when they were doing well. During our testing it became apparent that the idea of arrow bombs was not enough to make it more interesting than DDR. It needed more. A weird combination of "eureka!" and a mis-communication with one of our artists was what spawned the idea of having lots of different types of attacks. We knew we were on to something there and had to pursue it. Later on we realized also that if we actually finished this thing then we might be able to sell it and make money, and that meant a real business structure. So in November we filed for an LLC in Texas, and Cryptic Allusion, LLC was born as a "real" company at that point. All of FoF and all of our future productions are now under that banner. '''Every time Feet of Fury is shown at game shows it gets a rather large presence of people around it. Do you feel Feet of Fury stands up well in arcade like areas with the likes of DDR?''' Well, as you probably know, a creator of a work is never entirely pleased with the results. :) I think FoF could have been more than it is. Even so, ignoring the new features we've added that have made FoF a different game from DDR, I believe the "feel" of FoF is actually better. As a long time DDR player, I prefer to play FoF at this point, and given the self-criticism I mentioned above, I think that's a pretty important statement. I won't name any names, but we had some serious interest from a big-name company in an early publishing deal on FoF and they did some testing of the game with some of the DDR scene's biggest players. They were dubious at first but played for quite a while and liked it. I believe if we were able to go back and make FoF arcade machines with real, industrial-strength pads, and tons of music, we could take on DDR any day. Especially if people could bring their own Swap CDs to the arcade and play their own music, or arcades could provide their own Swap CDs to diffrentiate themselves from competing arcades (we had the competing arcades a lot in Austin). People love DDR but they are tired of Konami delivering the same game over and over with small tweaks in each edition, and increasingly annoying music. I know people who like the DDRMAX series, but most DDR people I know talk about the "good ol' days" of 4th and 5th mix. People are itching for something new and I'm sad that we can't provide that with our current operation. '''Is there anything that you wish Feet of Fury could have had if it had a bigger budget and a longer development cycle?''' I think Roddy covered this pretty well in his interview, but basically we would have liked to have had more music and better graphics (the part I worked on; our character artists were FANTASTIC). We would have liked to have actual animated characters with voice acting, acting out their fight in the background just like Puzzle Fighter or Puyo Puyo. We'd have loved to have an anime intro sequence encoded in high quality Ogg Theora. Most of all I would have liked more time to do several rounds of play testing to flesh out what works well and what doesn't in the gameplay. I think some of that is fairly rough still. I'm somewhat unhappy with the cleanliness of the code as well, but I ended up refactoring a lot of it about 10 times, which resulted in some nice free libraries like Parallax and Tsunami for all KOS users. It could have been a lot worse, so I think we did quite well within the constraints we had. '''How did you come up with the idea for the Typing of Fury mode?''' The real origins of ToF are somewhat apocryphal at this point -- I searched our email list archives and I honestly can't find the email that started it all, but I know the idea was first presented around the end of September a little after IGF. I think I originally proposed it. It's the sort of twisted thing that would come out of my head. Typing of Fury was one of those "nooooo freaking waaay" additions to the game that happened kind of late, but I'm very happy we included it because it's extremely original. It really sets us apart from the other rhythm games. As far as I know, no one has ever made a typing rhythm game before. I am actually happier with ToF than the main FoF "item battle" mode because we got to do a few rounds of tester feedback and improve the gameplay dramatically before it became a huge investment to redo it. As an aside, an excerpt from our mailing list that I can't avoid throwing in from my friend David, rejected announcer voice ideas: "YES, my PRECIOUSSSSS... DANSSSES IT DOESSSS, YESSSS!" '''What are your thoughts on the commercial future of the Dreamcast in the homebrew realm?''' There are some really fantastic possibilities there, but there are definitely some stumbling blocks. I think a lot of it's going to depend a great deal on whether people can feel good sticking with it instead of heading to the "next big thing". By that I mean, do you feel good continuing to make 100% legal and sellable games for a slightly dead system, or do you have to have the newest, like Xbox or PS2? And I think it depends too on whether people continue to buy new homebrew Dreamcast games even though the system isn't commercially produced anymore. I have actually been fairly baffled by the lack of interest in this so far, compared to bigger homebrew scenes, considering that authors are still making loads of cash on very old systems like the Vectrix and Atari 2600. I can tell you, anyone who is out there thinking about making a DC homebrew title, if you complete it and it looks professional, there are several people who'd be happy to publish it for you. The market is starting slowly and small but it is there. Another big stumbling block is one that is present in any sort of creative undertaking: deciding when enough's enough. A group of four guys plus a handful of outside musicians produced FoF in our free time, and it took us several years. And FoF isn't such an amazing product for several years' worth of work; we vastly underestimated the required effort. So many DC homebrew projects are started with HUGE ambitions like "create a full RPG". That's a really noble goal, but it's simply not possible, especially as a first project. I think DC Tonic and FoF were way beyond where Cryptic Allusion should have been at the time, and the only way we finished them was by putting in an incredible amount of obsessive effort, lost sleep and sanity, etc. Developers are going to need to get their teams going reliably and start kind of small. The most important thing is to _finish a project_. Your first completed project is not going to be a masterpiece; it doesn't have to be. The goal is to get momentum going for yourself and your team so that you can work up to greater and greater things, attract more talent, get contacts, and ultimately make that really awesome game you want to make. And hey, who knows, maybe you will have gotten enough attention then to get published on a still-active console. I urge anyone who's seriously interested in all of this to contact me at dpotter@cagames.com, and I'll be happy to discuss it with you. '''Do you think that shareware can work in the Dreamcast market?''' Absolutely. I believe shareware is the way to kickstart the DC homebrew market. I think that what we are really going to have to work on, to make it work right, is the delivery. There was an argument about this on our forums, but there are essentially two types of shareware: *1) Download and try a demo; if you like it, send money and you get a full professionally pressed CD and manual in the mail like a "real" game; *2) Download a limited version; if you like it, send money and they'll send you more levels, a code to unlock new areas, etc. The first one is easy, but it requires some manufacturing costs up front, which make it kind of less attractive for smaller developers (which still mostly includes us). FoF is proof that the first option is quite feasible if you have some investment. What you really want for kickstarting the market is the second option, so people can sell little one-off puzzle and fighting games for $5 a pop or something. These make great impulse buys, and you're supporting the game makers you like directly. The problem there is that the decent communications peripherals for the DC are rare, and there was no real persistent storage produced. So you'd need a very reliable and uniform way to burn the games to a CDR on a PC. And as we probably all know, that just hasn't happened. What it's going to have to happen is that someone needs to make a delivery mechanism that is extremely easy and transparent to use for buying the games and burning these games to the customer's CDRs. Self-Boot Inducer (SBI) and Dream Inducer (DI) are a great start there, but I think there needs to be a more polished and integrated package to handle the whole task, and it needs to support all platforms (PC, Mac, Linux). Ideally something along the lines of iTunes(tm), but for DC games: browse the store, check out preview videos (and maybe demo versions), add the games you like to your cart, and then check out to get your "game bundles". Insert a CD and select the games you want on it, and tell it to burn. Out pops a bootable CD with a professional quality selection menu (or no menu perhaps if the user only burned one game to the disc). Once you have such a system, the "option #1" games will follow as the most popular authors get a following and earn enough money to fund better games and manufacturing. '''Any insight towards what Cryptic Allusion has planned for the future?''' First and foremost, we are planning to continue to make DC homebrew titles for as long as we can stand it. :) Another project is now in the works which will probably be announced officially by the time this magazine is published. Second, I am going to continue to maintain and improve KallistiOS for the community as long as I can, and through me CA will be contributing a lot of code to the community from our projects. Numerous improvements to KOS which have become quite important to the community now (such as the new PVR system, KGL, and the new Maple system) were started so that we could write FoF. Much code has been contributed directly from FoF as well, such as the Parallax and Tsunami libraries. We plan to continue this trend with future projects and eventually release the full sources for all of our game projects under a free license somewhat like ID with the old Wolf, Doom, etc. Third, we plan to continue our market building strategies for the DC homebrew community. This involves making and selling more games of our own, and perhaps some of the infrastructure support for the shareware model I mentioned above. I'm convinced that approach would make things really take off, and I'd like to help jumpstart it. 296e4b5d5f6e3b9290f99f513ca1f192c91ba680 Titres 0 1056 2262 2023-03-02T05:16:16Z Unknown user 0 Created page with "Developer: [http://jimbomania.com/ Jimbo] Version: 0.0.7 Last Updated: Thursday, May 9, 2002 Description: A tetris clone. [http://www.dcemulation.org/files/software/d..." wikitext text/x-wiki Developer: [http://jimbomania.com/ Jimbo] Version: 0.0.7 Last Updated: Thursday, May 9, 2002 Description: A tetris clone. [http://www.dcemulation.org/files/software/dihbNero.zip Nero image] [http://www.dcemulation.org/files/software/dihbDJ.zip DJ image] [http://www.dcemulation.org/files/software/titres007.zip Plain files] 0330f3ff935663b82ab9df7a9c1c5a130af18891 DreamSNES 0 830 2263 1978 2023-03-02T05:16:56Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSNES| image=[[File:Dreamsnesmainmenu.jpg|center|250px]]| homepage=[http://mc.pp.se/dc/dreamsnes/ Homepage]| version=0.9.8| downloads=[http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files]<br/>| release date=10/31/2002| author=[[Marcus Comstedt]]<br/>[[Peter Bortas]]<br/>[[Per Hedbor]]<br/>| original=Snes9x<br/>(Snes9x Team)| systems=Super Nintendo| best=No, try<br/>[[SNES4All|Snes4All]]| refreshrate=50Hz/60Hz| isactive=No }} ==History== DreamSNES is a port of the Snes9x [[Super NES]] emulator for Dreamcast, developed by [[Marcus Comstedt]], [[Peter Bortas]], and [[Per Hedbor]]. It is not completely fullspeed, but it can run near-fullspeed with some tweaking. It features capabilities to save games to the VMU, an optional TV-mode for creating a TV-like feel when being played on a VGA monitor, four controller support, mouse, keyboard, and lightgun support, hidden games, ROMs list support, great artwork by Kathy Choi, and groovy music by Jan Warnstam. It was translated to a high number of languages, including Finnish, French, German, Italian, Japanese, Polish, Portuguese, Romanian, Spanish, and Swedish. It was the best Snes emulator on the Dreamcast scene for many years, leaving behind a secure legacy. =Downloads= * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files] * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8-cdi.zip DiscJuggler] * 0.9.8 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.8-nero.zip Nero] * 0.9.7 - [http://www.dcemulation.org/files/emulators/dreamsnes/dreamsnes-0.9.7.zip Plain Files] =Related tools= * [http://dcemulation.org/1-newsdump/emulators/dreamsnes/Provlist.zip Provlist]<br /> * [http://dcemulation.org/1-newsdump/emulators/dreamsnes/romlst-1.2.zip RomList] =Links= * [http://www.lysator.liu.se/dreamsnes/tutorial/ Burning tutorial written by the DreamSNES team]<br /> * [http://peter.bortas.org/dreamsnes/faq.html Official DreamSNES FAQ]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21208 Bug/compatability list]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21518 nakamichi's bug/compatibility list] =Interview with DreamSNES team= This is an interview with [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]], the creators of [[DreamSNES]]. It was taken by Wraggster in 2001. '''DCEmulation.com: Hi, Can you please Introduce yourself?''' Peter: Hi, I'm Peter Bortas. I work together with Marcus and Per on an Internet Software company called Roxen. Marcus: Hi, I'm [[Marcus Comstedt]]. I work together with Peter and Per on an Internet Software company called Roxen (is this getting silly now?) Per: Hi, I'm [[Per Hedbor]]. I work together with Peter and Marcus on an Internet Software company called Roxen (is this getting silly now?) '''DCEmulation.com: What is your background experience with emulators, which ones do u use?''' Peter: As all ComputerSience students I've written a few emulators in and out of class. None other than DreamSNES that are released though. I rarely use emulators but when I do it's either Snes9X to play some old cRPG, or VICE to check out old and new Demos for the C64. Marcus: Well, I've also written a few emulators in my day. For the Amiga I wrote a TI-99/4A emulator and an ABC80 (Swedish computer) emulator. I've been involved in writing an Amiga emulator that runs on Sun SPARC. The most bizarre emulator I've made was a C64 emulator implemented entirely in LISP(!). The only emulator I've released previously though is the multiplatform Visual Memory emulator (SoftVMS). As for using emulators, I sometimes use the Fusion Macintosh emulator on my Amiga, and I use VGB for doing GameBoy development. Per: Well, I have written an 6808 emulator (purely CPU emulation, way back, in '91 or so), and started a few others, but nothing really useful. I only use emulators to play some FFII now and then. '''DCEmulation.com: When did you start to get involved with DreamSnes, How exactly are you involved with this wonderful emulator For the DC?''' Peter: Let's see, according to CVS I made my first changes to the Snes9X source on June 30th. As for involvement, I poke around in all parts of the code except the mpeg player. Marcus: Well, I tend to work on the low level hardware support stuff, like controllers and memory cards and what have you. I'm also doing the assembler optimized CPU assembly core (whenever I get finished with that...) Per: I got involved at July the 28th 2000, according to CVS. I optimized the options to gcc, and messed around some with the code to get the binary size down. After that, I have been working on most part of the code, but mostly the menu system and the mpeg player. '''DCEmulation.com: Have you helped any other emu authors that are porting to the Dc. I know of one person that is working on a genesis emu for the DC. Maybe you can assist him?''' Peter: People ask me questions about making emulators (and other programs) now and then, and I usually answer them if they are well thought out. I'm not involved directly in any other emulator though. Marcus: I've been helping Chuck Mason a little with his [[Gleam!]], when he asked for it. Other than that, I can't say I've had much questions from people actually working on an emulator. Per: Not really, except for answering the odd question on the DCDev mlist. DCEmulation.com: Where did you meet Marcus Comstedt, Per Hedbor & Kathy Choi? (Please Tell Kathy that I love her art its the best) Peter: Per, Marcus and I met at the Lysator Academic Computer Society ([www.lysator.liu.se www.lysator.liu.se]). We were all taking classes at the same University. Kathy has a display of her pictures at a web gallery called Elfwood ([elfwood.lysator.liu.se elfwood.lysator.liu.se]) that I help administer, and when we asked to use one of her pictures as a background for DreamSNES she agreed and even made us the DreamSNES logo. I've said it before, but I really love Kathy for letting us use her pictures. '''DCEmulation.com: Why did you choose Snes9x to be the Super Nintendo emu you port to the DC?''' Peter: Well, it wasn't even an issue of choosing between emulators. Marcus was at that time giving out all sorts of information to the public about how the Dreamcast works internally as he found it out and documented it himself. I thought it would be fun to do something other than pure tests like printing some text to the screen. It should be something that gave quick results, was fun to play with and used as many parts of what Marcus had digged out about the Dreamcast as possible. Snes9X came to my mind because *1. You can play Final Fantasy on it. That's loads of fun. *2. You don't have to do any nice looking graphics, it's already in the game. Makes for quicker results. (We hadn't recruited Cathy yet.) *3. It has potential to use controllers, mice, light guns, display, 3D-hardware, Puru-Puru packs and lots more. *4. I had looked at Snes9X source before and know it to be well written and easily understood. '''DCEmulation.com: What is the Future of DreamSnes, what might be added to improve it?''' Peter: I will have my Puru-Puru support. The original SNES didn't have one you say? Bah, one shouldn't be stopped by such trivialities. Marcus: What really needs improvement is the burning procedure. My aim is to have an automated tool (platform independant of course) to handle the procedure. '''DCEmulation.com: What do you do in your spare time when your not online?''' Peter: Sleep, socialize with friends, read books. Marcus: Spare time? Not online? What do you mean? Per: Sleep and read books, mostly. '''DCEmulation.com: Do you think you will try to Port over any other emus to the DC for Ex: Mame, System32, Turbo graphic16, Callus or UltraHLE etc.?''' Peter: Maybe, I've been playing with another emulator, but it's all vapor right now. Marcus: I'll probably take a shot at porting over my old TI-99/4A emulator when DreamSNES 1.0 is finished. '''DCEmulation.com: Do you or anyone you know have any plans to port anything to the PS2?''' Peter: Yes, I have some vague plans, but I haven't been playing with my PS2 for a while. '''DCEmulation.com: Do you think that the Dreamcast is the best console to port Emulators to because it's Windows CE compatible and will it be dificult to port to the PS2?''' Peter: It's the best console to port emulators to at the moment because *a) the amount of publicly available information about how to code for it is only rivaled by the GameBoy, and *b) it's the first console to be fast enough to emulate the SNES generation of game machines. [[WindowsCE]] has very little to do with it. It wouldn't be that hard to port to the PS2 for someone who knows how the basic hardware works. Per: [[WindowsCE]] has nothing to do with how easy it is to port emulators to it, really, since it's not possible to release emulators using it. On the other hand, the hardware in the DC is really easy to code for, that's more important than the existence or non-existence of devkits that cannot be used. '''DCEmulation.com: If there was anything you wanted to say to the people that use your Emulator or fans of the Dreamcast what would that be?''' Peter: Save cities from certain annihilation! Find the hidden game in the DreamSNES X-mas release! [[Category:Emulator]] dea7a1d3281773fb39b281d8c66992f6a6b82111 File:Dcvcd.gif 6 1057 2264 2023-03-02T05:17:34Z Unknown user 0 wikitext text/x-wiki Dcvcd 50e202376bfe2c27834ee2cbb05ff4c7af23987d Dream VCD Player 0 1058 2265 2023-03-02T05:17:39Z Unknown user 0 Created page with "[[Image:dcvcd.gif|thumb]] {| |- |Developer: |[http://www.lik-sang.com/info.php?category=32&products_id=1175&lsaid=219793 LikSang] |- |Version: |1.0 |- |Price: |$26 |- |Descrip..." wikitext text/x-wiki [[Image:dcvcd.gif|thumb]] {| |- |Developer: |[http://www.lik-sang.com/info.php?category=32&products_id=1175&lsaid=219793 LikSang] |- |Version: |1.0 |- |Price: |$26 |- |Description: |Video CDs are fairly popular in Asia, where bounties of discs are hawked by street vendors for the equivalent of a couple of American dollars, if that. There erupted a hullabaloo a few years back when "The Phantom Menace" broke out on pirate video-cd at the same time as the theatrical release in the States. If you didn't mind the background noise from the audience (Initial bootlegs were DV'ed from screenings), the movie quality was passably viewable. Or so we've heard. NCS tested today's DC VCD player with a copy of Virtua Fighter 2 CGMV, a collection of cinemas featuring Sega's 3-D battlers, and it ran fine. The rear of the packaging touts VGA-Box support and the availability of a special controller. A quick check with vendors in Hong Kong deny the availability of a controller at this time but perhaps it'll launch soon. Packaging includes VCD accessory and boot disc. Finally you can also watch VCD (not DVD!) movies on your Dreamcast machine. The Dream VCD Player supports all usual functions such as forward, backward, volume control, etc. The attached remote allows wireless control of your movies. |} [http://www.lik-sang.com/info.php?category=32&products_id=1175&lsaid=21979 Order it Online Now] eee67c917a6e177b0697dfee50ad4f756a4e1688 File:Flash.jpg 6 1059 2266 2023-03-02T05:19:01Z Unknown user 0 wikitext text/x-wiki Flash b62482236f533b5e0f245e716211965a8774a2f2 File:FlashBack1.jpg 6 1060 2267 2023-03-02T05:19:09Z Unknown user 0 wikitext text/x-wiki FlashBack1 35f226ab5cd474be93750e4f10232688e33ebc2f REminiscence 0 1061 2268 2023-03-02T05:19:14Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | REminiscence |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | REminiscence |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Flash.jpg|thumb|280px| Flashback]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.1.8}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/flashback/REminiscence-0.1.8dc.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|11/19/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://cyxdown.free.fr/reminiscence/ REminiscence]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== REminiscence is a rewrite of the engine used in the game [http://en.wikipedia.org/wiki/Flashback_(video_game) Flashback] ''(in the US subtitled 'The Quest for Identity')'' from Delphine Software. This program is designed as a cross-platform replacement for the original executable and uses the SDL library. Original version by Gregory Montoir, 'cyx@users.sourceforge.net'. [[Image:FlashBack1.jpg|300px| Game Screen]] ===Controls=== Dreamcast Controller: * D-Pad → move Conrad * Start Button → display the options * A Button → talk / use / run / shoot * X Button → Draw weapon from holster * Y Button → use the current inventory object * B Button → display the inventory ''(Support for Dreamcast Keyboard as well) ===Needed files=== ''(Place in "Data" folder) * FB_TXT.FNT * GLOBAL.ICN * GLOBAL.FIB * GLOBAL.SPC * *.OFF * *.SPR * *.MAP * *.PAL * *.ANI * *.CT * *.MBK * *.OBJ * *.PGE * *.RP * *.TBN * *.CMD * *.POL * *CINE.* If you have a version distributed by SSI, you'll have to rename some files : * LOGOSSSI.cmd → LOGOS.cmd * LOGOSSSI.pol → LOGOS.pol * MENU1SSI.map → MENU1.map * MENU1SSI.pal → MENU1.pal You will need the Amiga MOD files listed in the readme, renamed without the ".mod" extension, if you want sound during the cut scenes. * ''Example: '''mod.flashback-voyage.mod''' → '''mod.flashback-voyage''' * Windows users can use command line renaming. Navigate to the folder containing the '.mod' files, and enter the following command. '''rename *.mod *..''' ===How to Burn=== Place the game's datafiles in the directory 'Data', and the amiga mod files into the same 'Data' folder. Place the 'Data' folder, with the 1st_read.bin, into a root folder. Selfboot ''(scramble the binary)'' that folder with [[BootDreams]]. ==Downloads== * REminiscence 0.1.8 - [http://dcemulation.org/1-newsdump/games-demos/flashback/REminiscence-0.1.8dc.rar Plainfiles] - 11/19/2005 * REminiscence 0.1.8 - [http://dcemulation.org/1-newsdump/games-demos/flashback/REminiscence-0.1.8src.rar Source] - 07/31/2005 * REminiscence 0.1.2 - [http://dcemulation.org/1-newsdump/games-demos/flashback/REminiscence-0.1.2src.rar Source] - 02/07/2005 f414bf2fd571fb8371800d3baea2051b6efc1fd6 Shuffle 0 1062 2269 2023-03-02T05:19:45Z Unknown user 0 Created page with "Shuffle http://www.dcemulation.com/dl/dl.php3?url=files/software/Shuffle-DJ-img.zip" wikitext text/x-wiki Shuffle http://www.dcemulation.com/dl/dl.php3?url=files/software/Shuffle-DJ-img.zip 8460a586944344570013a1ab6151ae63afb117d6 File:Icon e sad.gif 6 1063 2270 2023-03-02T05:23:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Icon e sad}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 021efc59a7c12ac81356c26efe89667b5adc4fbf File:Icon e biggrin.gif 6 1064 2271 2023-03-02T05:23:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Icon e biggrin}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b4ff51262ac9a7f567973c84bda4061727c39eec File:Icon cry.gif 6 1065 2272 2023-03-02T05:23:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Icon cry}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c26c5e8f036daa5ac838e5a4621a98618cf1d9a1 File:Icon e smile.gif 6 1066 2273 2023-03-02T05:23:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Icon e smile}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 85e0670484bd467823807e70c8053e8d0b54e949 File:Icon neutral.gif 6 1067 2274 2023-03-02T05:23:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Icon neutral}} |date=2023-03-01 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 38990f8d7e5c1c5b8debd4a533e0d707c75591be SNES4All 0 838 2275 1988 2023-03-02T05:23:50Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SNES4ALL| image=[[File:snes4all.png|center|250px]]| homepage=[http://chui.dcemu.co.uk/snes4all.html Homepage]| version=Beta 1| downloads=[http://chui.dcemu.co.uk/releases/snes4all-beta1.rar Plain Files]<br/>[http://chui.dcemu.co.uk/releases/snes4all-src-beta1.tar.bz2 Source Files]<br/>| release date=03/28/2011| author=[[Chui]]| original=[http://www.snes9x Snes9x]<br/>(Snes9x Team)| systems=Super Nintendo| best=Yes| refreshrate=50Hz/60Hz| isactive=Yes| }} ==About== SNES4ALL is a port of Snes9x to the Dreamcast by the very well kown Spanish Dreamcast coder [[Chui]]. ==Features== * Hardware scaled resolution. * Assembler CPUs core enabled. * Auto frameskip for real speed. * Save state and SRAM. * VMU and SD-Card support. * Operative Menu: Throttle, Frameskip, Transparency, Sound * File-manager with sub-directories access. * 4 joysticks emulated. * Under PAL Dreamcasts ask 60-50Hz selection ==Downloads== * ''Beta-1 - [http://chui.dcemu.co.uk/releases/snes4all-beta1.rar Plain Files] - 03/28/2011 * ''Beta-1 - [http://chui.dcemu.co.uk/releases/snes4all-src-beta1.tar.bz2 Source Files] - 03/28/2011 * ''Alpha-3 - [http://www.qfpost.com/download.do?get=bdefe8b78c9c8a2bbacffe01819654d2 Plain Files] - 03/27/2006 * ''Alpha-3 - [http://www.qfpost.com/download.do?get=fea7ed6d0da16994159c8f3a2f4db136 Source Files] - 03/27/2006 * ''Alpha-2 - [http://www.qfpost.com/download.do?get=ce3eb599c5b52d6898e80b7e7f182ad2 Plain Files] - 03/19/2006 * ''Alpha-2 - [http://www.qfpost.com/download.do?get=fd54df6566720888c6c614f50e5ad5bc Source Files] - 03/19/2006 ==Compatibility List== This compatibility list is for the Alpha 3 release. ==Key/Guide== [[image:icon_cry.gif]] = Unplayable/Doesn't work<br/> [[image:icon_e_sad.gif]] = Poor<br/> [[image:icon_neutral.gif]] = Okay<br/> [[image:icon_e_smile.gif]] = Good<br/> [[image:icon_e_biggrin.gif]] = Great<br/> T = Throttle<br/> FS = Frameskip<br/> (*) = Tranparencies turned off The listing order is "game name", "rating", and then "recommended setting". ==List== 7th Saga (U) = [[image:icon_neutral.gif]] , T-25/ FS-3 Actraiser (J) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Actraiser (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Actraiser (E) = [[image:icon_e_smile.gif]], T-75/ FS-2/ * Actraiser 2 (E) = [[image:icon_e_sad.gif]] , T-75/ FS-3/ * Addam's Family Values (E) = [[image:icon_cry.gif]] Aero the Acrobat (E) = [[image:icon_neutral.gif]] , T-75/ FS-2 (BGM problems) Aero the Acrobat 2 (U) = [[image:icon_neutral.gif]] , T-75/ FS-2 (BGM problems) Aerobiz Supersonic (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Aladdin (U) = [[image:icon_neutral.gif]] , T-/25 FS-3 Alcahest (J) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Alien 3 (U) = [[image:icon_neutral.gif]] , T-50/ FS-3/ * Alien Vs Predator (E) = [[image:icon_neutral.gif]] , T-100/ FS-2 Animaniacs (U) = [[image:icon_neutral.gif]] , T-50/ FS-3/ * Animaniacs (E) = [[image:icon_neutral.gif]] , T-50/ FS-2/ * Another World (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2 Assault Suit Valken (J) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Asterix (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Asterix Obelix (E) = [[image:icon_neutral.gif]] , T-75/ FS-2/ * Bahumat Lagoon (J) = [[image:icon_neutral.gif]] , T-50/ FS-3 Ballz 3D (U) = [[image:icon_cry.gif]] , T-75/ FS-3 Bass Master Classic Pro Edition (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Battletoads and Double Dragon (U) = [[image:icon_e_smile.gif]] , T-50/ FS-1/ * Battletoads and Double Dragon (E) = [[image:icon_e_biggrin.gif]] , T-50/ FS-1/ * Blackhawk (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2 Blackthorne (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * B.O.B. (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Brain Lord (U) = [[image:icon_e_sad.gif]] [[image:icon_cry.gif]] , T-25/ FS-3 Breath of Fire II (U) = [[image:icon_e_sad.gif]] , T-100/ FS-3 BS The Legend of Zelda: Kodai no Sekiban (J) = [[image:icon_e_smile.gif]] , T-25/ FS-(3 or 2) Bust A Move (U) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Cannon Fodder (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2 Captain America & The Avengers (U) = [[image:icon_neutral.gif]] , T-75/ FS-3/ * Captain America & The Avengers (E) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Captain Commando (E) = [[image:icon_neutral.gif]] , T-75/ FS-2/ * Castlevania Dracula X (U) = [[image:icon_cry.gif]] , T-75/ FS-3 Chaos Engine (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Chessmaster (U) = [[image:icon_e_smile.gif]] , T-0/ FS-2 Clayfighter 2 (U) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Clayfighter 2 (E) = [[image:icon_neutral.gif]] , T-75/ FS-2/ * Claymates (U) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Clock Tower (J) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Contra 3 (U) = [[image:icon_cry.gif]] , T-0/ FS-3/ * Death & Return of Superman (U) = [[image:icon_e_smile.gif]] , T-25/ FS-3/ * Death & Return of Superman (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Demon's Crest (U) = [[image:icon_e_sad.gif]] , T-25/ FS-2/ * Der Langrisser (U) = [[image:icon_cry.gif]] Desert Strike (U) = [[image:icon_e_smile.gif]] , T-50/ FS-1 Desert Strike (E) = [[image:icon_e_smile.gif]] , T-50/ FS-2 Dirt Trax FX (U) = [[image:icon_cry.gif]] , T-75/ FS-3 Do-Re-Mi Milon's Quest (J) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Donkey Kong Country (U) = [[image:icon_neutral.gif]] , T-75/ FS-3/ * Donkey Kong Country (E) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Donkey Kong Country 2 (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Donkey Kong Country 3 (U) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Doom (E) = [[image:icon_cry.gif]] , T-100/ FS-3/ * Dungeon Master (U) = [[image:icon_neutral.gif]] , T-75/ FS-2 Earthworm Jim (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Earthworm Jim 2 (U) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Earthworm Jim 2 (E) = [[image:icon_e_sad.gif]] , T-75/ FS-2/ * F-Zero (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Famicom Tantei Club Part II (J) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Fatal Fury 2 (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Fatal Fury Special (E) = [[image:icon_e_sad.gif]] , T-25/ FS-2/ * Final Fight (E) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Final Fight 2 (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Final Fight 3 (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2 Final Fight Guy (U) = [[image:icon_e_sad.gif]] , T-25/ FS-3 First Samurai (E) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Flashback (U) = [[image:icon_e_smile.gif]] , T-50/ FS-2 Flashback (E) = [[image:icon_e_smile.gif]] , T-50/ FS-2 Harvest Moon (U) = [[image:icon_neutral.gif]] , T-25/ FS-3 Harvest Moon (E) = [[image:icon_neutral.gif]] , T-25/ FS-2 Ignition Factor (U) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Incredible Hulk (U) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Incredible Hulk (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Indiana Jones Raiders of the Lost Ark (U) = [[image:icon_e_sad.gif]] , T-50/ FS-3 Inindo (U) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Iron Commando (E) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * JRR Tolkien's The Lord of the Rings (E) = [[image:icon_neutral.gif]] , T-25/ FS-3 Jelly Boy 2 (Beta) () = [[image:icon_e_smile.gif]] , T-25/ FS-2 Jeopardy (U) = [[image:icon_e_smile.gif]] , T-0/ FS-2 Jeopardy Deluxe Edition (U) = [[image:icon_e_smile.gif]] , T-0/ FS-2 Jeopardy Deluxe Edition (E) = [[image:icon_e_smile.gif]] , T-0/ FS-2 Jerry Boy (J) = [[image:icon_e_smile.gif]] , T-0/ FS-2 Judge Dredd (E) = [[image:icon_e_sad.gif]] , T-100/ FS-3 Jungle Strike (U) = [[image:icon_e_smile.gif]] , T-0/ FS-2/ * (Minor sound & gfx errors) Jungle Strike (E) = [[image:icon_e_smile.gif]] , T-0/ FS-2/ * (Minor sound & gfx errors) Jurassic Park (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Jurassic Park 2 - Chaos Continues (U) = [[image:icon_neutral.gif]] , T-25/ FS-(2 or 3) (Depending on stage) Jurassic Park 2 - Chaos Continues (E) = [[image:icon_neutral.gif]] , T-25/ FS-(2 or 3)(Depending on stage) Justice League Task Force (E) = [[image:icon_neutral.gif]] , T-100/ FS-2/ * Killer Instinct (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * (Stage gfx errors with transparencies off) Killer Instinct (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * (Stage gfx errors with transparencies off) King Arthur & the Knights of Justice (U) = [[image:icon_e_smile.gif]] , T-50/ FS-2 King Arthur's World (U) = [[image:icon_e_smile.gif]] , T-0/ FS-3/ * King of Dragons (U) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Kirby's Superstar (U) = [[image:icon_cry.gif]] Kirby's Avalanche (U) = [[image:icon_neutral.gif]] , T-100/ FS-2/ * Kirby's Dream Course (U) = [[image:icon_neutral.gif]] , T-0/ FS-2/ * Kirby's Dream Land (U) = [[image:icon_cry.gif]] Kirby's Fun Pak (E) = [[image:icon_cry.gif]] Kirby's Ghost Trap (E) = [[image:icon_neutral.gif]] , T-100/ FS-2/ * Knight's of the Round (U) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Legend of Mystical Ninja (U) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Legend of Mystical Ninja (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Legend of Zelda (U) = [[image:icon_neutral.gif]] , T-100/ FS-3 Lemmings (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Lemming 2 (E) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Lion King (U) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Lion King (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3/ * Little Magic (J) = [[image:icon_neutral.gif]] , T-75/ FS-Auto Lost Vikings (U) = [[image:icon_e_smile.gif]] , T-25/ FS-3/ * Lost Vikings (E) = [[image:icon_neutral.gif]] , T-75/ FS-3/ * Lost Vikings 2 (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Lost Vikings 2 (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Lufia Fortress of Doom (U) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Lufia 2 (U) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Lufia 2 (E) = [[image:icon_e_biggrin.gif]] , T-0/ FS-2 Madou Monogatari (J) = [[image:icon_neutral.gif]] , T-75/ FS-3 Magical Pop'n (J) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Mario & Wario (J) = [[image:icon_e_biggrin.gif]] , T-0/ FS-2/ * Marvel Super Heroes - War of the Gems (U) = [[image:icon_neutral.gif]] , T-100/ FS-(2 or 3) (depending on stage) Marvel Super Heroes - War of the Gems (E) = [[image:icon_neutral.gif]] , T-25/ FS-(2 or 3) (depending on stage) Mask, The (E) = [[image:icon_neutral.gif]] , T-75/ FS-2/ * Mega Man X (U) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Mega Man X 2 (U) = [[image:icon_e_sad.gif]] , T-75/ FS-3 Mega Man X 2 (E) = [[image:icon_e_sad.gif]] , T-75/ FS-3 Mega Man X 3 (U) = [[image:icon_e_sad.gif]] , T-75/ FS-3 Mega Man 7 (E) = [[image:icon_e_sad.gif]] , T-75/ FS-3 Mega Man Soccer (U) = [[image:icon_neutral.gif]] , T-75/ FS-2/ * Mechwarrior (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Mechwarrior (E) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Metal Marines (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Might & Magic II (E) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Might & Magic III (E) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * Mobile Suit Gundam - Cross Dimension (J) = [[image:icon_e_smile.gif]] , T-25/ FS-3 Monopoly (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2 Mortal Kombat (E) = [[image:icon_e_sad.gif]] , T-75/ FS-3/ * Mortal Kombat 2 (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3/ * Mortal Kombat 3 (E) = [[image:icon_e_sad.gif]] , T-100/ FS-3/ * Mutant Chronicles - Doom Troopers (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Ninja Warriors (U) = [[image:icon_neutral.gif]] , T-50/ FS-3/ * Ninja Warriors (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3/ * Ninja Gaiden Trilogy (U) = [[image:icon_neutral.gif]] , T-25/ FS-3 Out of this World (U) = [[image:icon_e_smile.gif]] , T-75/ FS-2/ * Outlander (E) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Pacman - The New Adventures (U) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Paperboy 2 (E) = [[image:icon_e_smile.gif]] , T-50/ FS-2 Parodius (E) = [[image:icon_e_sad.gif]] , T-50/ FS-3/ * Parodius (J) = [[image:icon_e_sad.gif]] , T-75/ FS-3/ * Pitfall - The Mayan Adventure (U) = [[image:icon_neutral.gif]] , T-50/ FS-3/ * Pitfall - The Mayan Adventure (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Popful Mail (J) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Power Instinct (U) = [[image:icon_e_sad.gif]] , T-25/ FS-3/ * Prince of Persia (E) = [[image:icon_e_biggrin.gif]] , T-25/ FS-2/ * Prince of Persia 2 (E) = [[image:icon_e_smile.gif]] , T-50/ FS-2 Puzzle Bobble (E) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Realm (E) = [[image:icon_e_sad.gif]] , T-50/ FS-3 Rockman & Bass (J) = [[image:icon_neutral.gif]] , T-100/ FS-3 Scooby Doo Mystery (U) = [[image:icon_neutral.gif]] , T-100/ FS-2/ * Seiken Densetsu 3 (J) = [[image:icon_neutral.gif]] , T-25/ FS-3 Shadowrun (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Shanghai 2 (U) = [[image:icon_neutral.gif]] , T-75/ FS-2/ * Shin Kidou Senki Gundam Wing (J) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Shin Megami Tensei (J) = [[image:icon_neutral.gif]] , T-75/ FS-3 Shin Megami Tensei 2 (J) = [[image:icon_e_smile.gif]] , T-50/ FS-2/ * Sim Ant (U) = [[image:icon_neutral.gif]] , T-25/ FS-Auto/ * Simpsons - Bart's Nightmare (E) = [[image:icon_e_smile.gif]] , T-50/ FS-Auto/ * Soldiers of Fortune (U) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Space Invaders (U) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Spiderman & Venom - Maximum Carnage (U) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Spiderman & Venom - Maximum Carnage (E) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Spiderman & Venom - Seperation Anxiety (U) = [[image:icon_neutral.gif]] , T-25/ FS-3 Spiderman & Venom - Seperation Anxiety (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Starfox (U) = [[image:icon_cry.gif]] , T-75/ FS-3/ * Starfox 2 (J) = [[image:icon_cry.gif]] , T-25/ FS-3/ * Star Ocean (J) = [[image:icon_cry.gif]] , Graphic encryption not supported Star Trek - Deep Space Nine (U) = [[image:icon_e_smile.gif]] , T-25/ FS-2/ * Star Trek - Deep Space Nine (E) = [[image:icon_e_smile.gif]] , T-25/ FS-2 Star Trek - The Next Generation (U) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Star Trek - The Next Generation (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3 Stargate (U) = [[image:icon_neutral.gif]] , T-25/ FS-3/ * Stargate (E) = [[image:icon_e_sad.gif]] , T-25/ FS-3/ * Street Fighter Alpha 2 (U)/(E) = [[image:icon_cry.gif]] , Graphic encryption not supported Street Fighter 2 Turbo (E) = [[image:icon_neutral.gif]] , T-25/ FS-2/ * (If turned up to 3 or 4 stars, it plays very well.) [[Category:Emulator]] 258b3792aacabb5fa52279495e483071c98178ed File:Rchange.png 6 1068 2276 2023-03-02T05:26:17Z Unknown user 0 wikitext text/x-wiki Rchange 30eaa4ff750e975ea383b0aad023bfad5d31b86f Region Changer 0 1069 2277 2023-03-02T05:26:21Z Unknown user 0 Created page with "{{Infobox_Tools_Information| name=Region Changer| image=[[Image:Rchange.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.3| downloads=[ht..." wikitext text/x-wiki {{Infobox_Tools_Information| name=Region Changer| image=[[Image:Rchange.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.3| downloads=[http://dchelp.dcemulation.org/?download=rchange_03.zip Binary]<br />[http://dchelp.dcemulation.org/?download=rchange_03_src.zip Source]| release date=6/05/2007| author=fackue| isactive=Yes }} This tool was made to convert dc_flash.bin files into a specific Dreamcast region. Inspired by Region Changer for the DC hardware, this is to be used on Windows to convert the DC's region so it can be used in a emulator. b7a00571916acd027d17a4672db7ec1a6e624fe7 2278 2277 2023-03-02T05:26:27Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=Region Changer| image=[[File:Rchange.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.3| downloads=[http://dchelp.dcemulation.org/?download=rchange_03.zip Binary]<br />[http://dchelp.dcemulation.org/?download=rchange_03_src.zip Source]| release date=6/05/2007| author=fackue| isactive=Yes }} This tool was made to convert dc_flash.bin files into a specific Dreamcast region. Inspired by Region Changer for the DC hardware, this is to be used on Windows to convert the DC's region so it can be used in a emulator. af561124e6aa92039603eaeeaef63026fc182a21 Neill Corlett 0 1070 2279 2023-03-02T05:26:57Z Unknown user 0 Created page with "Neil Corlett was a Dreamcast programmer. He ported [[Beats of Rage]] to the Dreamcast and the PS2 in 2003. After [[Beats of Rage]] had become a huge success on the Dreamcast,..." wikitext text/x-wiki Neil Corlett was a Dreamcast programmer. He ported [[Beats of Rage]] to the Dreamcast and the PS2 in 2003. After [[Beats of Rage]] had become a huge success on the Dreamcast, he became a member of [[Senile Team]], the group who had developed Beats of Rage for the PC. 60d9603562c54eeb899610b6331a86f447baff0d File:Alien-sdl.jpg 6 1071 2280 2023-03-02T05:28:53Z Unknown user 0 wikitext text/x-wiki Alien-sdl 378e09f691c99f12030d7ccf208f70fbacaa13db Aliens 0 1072 2281 2023-03-02T05:28:55Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aliens |- border="0" cellpadding="2" cellspacing="1" al..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aliens |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Alien-sdl.jpg|center|thumb|240px| Aliens]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/aliens-SDL_DC.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|Will Sams}}} |- style="background:#ffffff" |Type of game || {{{type|Space Invaders Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== A silly little invading aliens type game -- just an example of using SDL with the mixer library. You only get one life -- stop those aliens from landing on you! ===Requirements=== * Dreamcast keyboard ===Controls=== * <space> → Fire (3 shots available) * <right arrow> → Move right * <left arrow> → Move left * <escape> → Quit the game ==Downloads== * 1.0.2 - [http://dcemulation.org/1-newsdump/games-demos/aliens-SDL_DC.zip Plain Files] - 06/07/2003 45eb57eab09b64b9a6331eccb3640d0d3417ac0c 2282 2281 2023-03-02T05:29:12Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aliens |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Alien-sdl.jpg|center|thumb|240px| Aliens]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/aliens-SDL_DC.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|Will Sams}}} |- style="background:#ffffff" |Type of game || {{{type|Space Invaders Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== A silly little invading aliens type game -- just an example of using SDL with the mixer library. You only get one life -- stop those aliens from landing on you! ===Requirements=== * Dreamcast keyboard ===Controls=== * <space> → Fire (3 shots available) * <right arrow> → Move right * <left arrow> → Move left * <escape> → Quit the game ==Downloads== * 1.0.2 - [http://dcemulation.org/1-newsdump/games-demos/aliens-SDL_DC.zip Plain Files] - 06/07/2003 e2ba0e23b16ff852546112628d6e8572354bb0e6 Feet of Fury 0 987 2283 2169 2023-03-02T05:38:11Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="2" | {{{name|Feet of Fury}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="2" | {{{image|[[Image:FeetOfFuryPackshot_p.jpg|250px|thumb|Copyright: Cryptic Allusion]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|http://www.cagames.com/}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>Purchase</i>}}} |- stylbackground:#ffffff" |Release Date || {{{release date|06/07/03}}} |- style="background:#ffffff" |Author || {{{author|Cryptic Allusion}}} |- style="background:#ffffff" |Type of game || {{{type|Dance Dance Revolution Clone}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==Independent Review== [[Image:FeetOfFuryScreen02_p.jpg|thumb|left|320px|Copyright: Cryptic Allusion]] Written by MetaFox, October 22, 2005 Source: [http://web.archive.org/web/20060918192734/http://dreamon.cyberdogcastle.com/index.php?n=Main.FeetOfFury DreamOn/CyberDogCastle via Archive.org] In 2003, Cryptic Allusion Games made history by releasing the first commercial independent Dreamcast game written with free development libraries. We did some extensive hands on playing of the game, and sat down with the creators of the game, Dan Potter and Roddy Toomim for a quick Questions + Answers session regarding Cryptic Allusion, Feet of Fury, and their upcoming game, Tryptonite. (The Q+A will be available in the print version of Dream On, available in the fourth quarter of 2005) Feet of Fury is a dancing game that borrows many elements from Konami's Dance Dance Revolution Series of games. You have a set of arrows that you must follow, while keeping your steps to the music. The main difference of Feet of Fury, and the element that sets it apart, is that the game is focused more on strategy and beating your opponent. There are power ups and power downs on the board. Hitting an arrow that contains an icon may cause the speed of the arrows to slow down or speed up, or it might cause the arrows to reverse direction. [[Image:FeetOfFuryScreen01_p.jpg|thumb|right|320px|Copyright: Cryptic Allusion]] Because of this element, the multiplayer mode in Feet of Fury is awesome. Another addition is the health bar. At the end of the round, the person with the most health is the winner. It adds a lot more to this type of game when you have to worry about your opponent hitting you with powerdowns, and throwing your feet around on the dance mat like an idiot, all while trying to keep your health bar full. The single player mode is no slouch either. There are a good number of songs to play and unlock. Each song has a good tempo to it, and fits this type of game really well. There are a number of hidden characters and features to be unlocked, so the game will keep you entertained for hours. When you get sick of all that dancing, you can let your fingers do the dancing with what is in my opinion, the coolest thing to happen to dance games since their invention: The Typing of Fury mode. In this mode, letters fly up on screen instead of arrows, and you use your Dreamcast keyboard to match the letters to the beat while spelling out words. This mode is very challenging, and surprisingly, very fun. When you add multiple keyboards to the action for some multiplayer mayhem, you'll see the pure hilarity that ensues. This is a top notch addition, and is a lot less of a gimmick than you might think. Take your dusty underused keyboards out of the attic, and set them up for some furious typing, you won't regret it. Summary: Good songs, multiplayer battle elements, unlockables, and Typing of Fury make this game a good investment, and an example for future independent developers to follow. '''Overall rating:''' 4 / 5 Purchase it at the [http://www.goatstore.com GOAT Store]. = Interview with Roddy, a.k.a. DJ Geki= This interview with [[DJGeki]] was taken by [[MetaFox]] for the DreamOn magazine #1, which was released at the Midwest Gaming Classic in 2004. '''How did you first become associated with Cryptic Allusion?''' This is a long story, so I'll try to get right to the point: I met Dan at the University of Texas through a mutual friend who wanted to start a game business within the next few years. Even though that company never got started, Dan's "demo group" named Cryptic Allusion was just kind of 'there' and we decided to make something of it after we got started on Feet of Fury. FoF was originally planned to be a free-release game, with just a few of my own songs in it. Nothing fancy...but it blew up into a full-size project after we decided that this might be our shot to "break into" the elusive boys-club that the industry seems to be. We're finally starting to see some of the effects of that now (i.e., EGM taking notice of the DC homebrew community), and I'd like to think that the commercial release of FoF had something to do with the rise in interest. '''What was your position for Feet of Fury?''' I played quite a few roles. I was first and foremost the primary composer of music and sound effects for FoF. I did around 20 tracks and loops specifically for the game. Don't even ask me to count how many sound effects I made. Secondly, I was the business contact and "department head" for all things that involved licensed music. I also gave a lot of feedback to Dan about gameplay, came up with some ideas for items/attacks present in the game, some menu structures, and other design ideas that never quite got to the "complete idea" phase. :) I also ended up vetoing some gameplay along with Dan so that the game would be a more enjoyable experience. That was mostly his idea, though... I think I'm a packrat when it comes to gameplay options. I almost never want to get rid of anything! '''Do you have a preference for the style of music that you make, or do you feel comfortable making music encompassing any genre?''' Woo...there's a toughie. A preference for the style of music I make... I'd like to say I don't have a preference. I enjoy dance music in general, but there are specific genres I don't like, and others that I prefer; however, I feel that if I needed to make something specific, I could do the research and make it happen (yes, even country music...FEH!). As was seen in the bonuses included on the FoF disc, I am capable of composing classical-type music. It may not be John Williams nor Mahler, but I kind of like what comes out of my brain. Now that I've danced around your question, let's see if I can answer it. I really like Breakbeat. I'd love to be able to get into doing some stuff that sounds more like it, but right now whenever I let my mind take over the music-making process, everything becomes jazz-like. Meaning, there's no real hook to most of my songs, as the melodic lines just tend to take themselves in whichever direction they please. '''Is there anything that you wish Feet of Fury could have had if it had a bigger budget and a longer development cycle?''' I think that if we'd had some capital, we might have paid for the first run of discs on our own. It's just technically simpler that way than going through a 3rd party. More specifically, we had planned for animated characters fighting in mid-screen (a la "Puzzle Fighter"), and a "charge up" mode that could have been extra special. It's way too involved to describe here, but it would have taken a longer amount of time to program this mode. It also would have removed FoF many steps away from DDR (no pun intended), not to mention that it was relatively intuitive, and made gameplay much more interesting. This mode could have replaced "Item Battle" as the main mode, but there wasn't enough time or complete ideas to make it happen. It broke quite a few rules from the standard DDR-style play. '''The thing that really makes Feet of Fury stand out from other music games is the typing of fury mode. What are your opinions on this feature?''' My opinion is that Dan is a freaky genius. Not a "Freaking Genius" (although he is that), but "freaky". I think he played "The Typing of the Dead" one too many times :D Excellent, excellent use of the existing engine to make up a totally different game. It's way too hard though :) It was all his idea, in case you couldn't infer that from my statements, but I really do enjoy getting my butt handed to me by the computer. '''What are your thoughts on the commercial future of the Dreamcast in the homebrew realm?''' The commercial future doesn't look amazing _right now_, but it's by no means going to go away or die. I think we're just off to a slow start.You give this scene another two years, and I think we may have an explosion of epic proportions on our hands. I mean, the DC is still new in the way of dead systems. Once our current lot of systems decides to die out, there will be a lull in terms of new games for the new slew of systems. In that time, we won't see anything interesting minus the "graphic demo" release titles that we're bound to see. You know the kind... the ones that "push 3D reality to the next level" and such. I just get this feeling that people are going to turn back to their old systems (like they usually do) and see that they had something great in the Dreamcast. Lots of quality games, the systems are super cheap (when you can find them), and the accessories are pretty much ubiquitous. Ooh...I used "ubiquitous"! (and it made sense!) '''There have been talks lately about making producingDreamcast shareware games as were done quite alot for the PC and Amiga in the early 1990s. What are your thoughts on this?''' I'm all for it! I LOVE shareware. I remember going to high school (way back in 1992-96) always having a store-bought shareware copy of Doom in my backpack. Any chance I got, I'd install that sucker on an 486 and impress the hell out of whoever was around. I used to go to the WaldenSoftware store in our local mall just so I could watch the bad-assness of the demos on the Amiga 500 they had on display. That was also the first time I'd ever seen "Shadow of the Beast". God bless thee, Psygnosis. Too bad Sony bought them out. In any case, I never had an Amiga until around 2 years ago, so I didn't really get into the demo scene back then. It looks like it was a good time for all from what I've seen recently of that era. Dan is the big proponent of DC shareware, and at first I was opposed to it. What section of the mass-market wants to download something for a console system? But the more I think about it, the more I like it: Johnny downloads the shareware, burns it to a disc and goes off to show his friends. They like it, so he gives them a copy legally. Legally? Wait a second...that shouldn't be! Ah, but it is my good consumer. Eat it up! Shareware games don't happen as much as they should these days. Let's hope this idea takes off. '''Any insight towards what Cryptic Allusion has planned for the future?''' Heh heh...i do i do. We hinted a bit at the RPG we had been working on (on the FoF disc) until we started in on Feet of Fury. I'd love to get a team to finish that. There is so much groundwork laid down, and yet so much left to do. It's just a project I'd love to take up again. Other than that, I came up with an idea for an online game that is quite unlike any games we've really seen here. It would require a relatively large budget (well, relatively large compared to $0.00), though, so don't look forward to that anytime soon. In any case, we do have lots of stuff planned, just nothing has been made solid yet as far as what our next project will be. I'd be expecting an announcement from us semi-soon, though. Maybe not something ground breaking, but definitely something worth looking forward to. Especially if you like old-school games. :D '''Thanks for taking the time to answer these questions, and sorry for procrastinating so much to get them to you.''' No prob. Hope you get these off in time to get them into the mag :) Good luck with it, and let us know when it's finished so I can buy a copy or twelve! BTW, it seems that Dan never received any questions, are you going to interview him as well? 4b2fadd016ee89b5901bfe07e71b7340b6b807b8 Tubooboo 0 1073 2284 2023-03-02T05:39:29Z Unknown user 0 Created page with "Tubooboo was a German Dreamcast developer. He released [[Ngine SNES9x]]. The latest Version (0.40) came out on March 22, 2001. It was using [[libdream]] and was one of the ear..." wikitext text/x-wiki Tubooboo was a German Dreamcast developer. He released [[Ngine SNES9x]]. The latest Version (0.40) came out on March 22, 2001. It was using [[libdream]] and was one of the earliest legal Dreamcast emulators. He also worked on an unreleased Genesis emulator based on DCGenerator called Nginesis and on an operating system for the Dreamcast, which was never released, too. == Interview == Below is an interview that was taken by dc_emumaniac from B00B! Dreamcast Research. ([[http://www.boob.co.uk]]) Since B00B! became inactive years ago, we published this interview here. '''B00B! Dreamcast Research: Hi Emanuel (tubooboo) can you tell us about yourself, and about your family, school, job, etc?''' Emanuel: Hi there, nice to see that people are still interested in what hapens at ngine.de although I did not do all this much on my stuff lately... ok , well I am not going to expose all my life, but i am 25 years old and work as a programmer since about 7 years. Computing-wise, I am doing programming since about 13 years now, starting out on a machine called the Amstrad CPC, moving on to the infamous Amiga where I learned Assembler. After that I became interested in console programming, and now personally own dev systems for SNES, GBC, NGPC, PSX , DC and all new now, the GB Advance. '''B00B: What made you choose the projects you have worked on so far? ''' Emanuel: fun really, I love Donkey Kong Country to bits and was fascvinated about the fact that there now were sufficiently fast consoles to run it on. Apparently, I did not take into account we could not use the x86 assembly CPU kernel, thats why all SNES9x ports are slow. [...] and old projects, yea, there was THC-Engine, a Amiga PC-Engine emu, anyone remember it? :) I also ran http://www.classicgaming.com/aec/ '''B00B: If you dont mind can you give us the fans a status report on each of your projects?''' Emanuel: Snes9x --> sound getting there., but expect no release for a while. Hugo --> this i will start to work on again regularly. Should be released in a few weeks, but no promises. '''B00B: What problems have you had and how did you overcome then?''' Emanuel: The biggest issue was getting the GNU debugger to work. I can’t really tell you how I did it, I cannot remember anymore, but it was tricky. '''B00B: What is your favourite Dreamcast emulator and what system would you like to see emulated the most and why? What is your opinion of the Emulator [[Bleemcast!]] from a technical point of view?''' Emanuel: I really like the completeness of [[NesterDC]]. [[Bleemcast!]] is a massive achievement technically, but then still a massive dissapointment from a bleem fans perspective. I personally like it, and will buy one for GT2 when I get the chance of grabbing it somewhere. '''B00B: What is your opinion of the Dreamcast Scene and what would you do to improve it to make it more accessible to new fans?''' Emanuel: The real "scene" was never all that easily accessible. It has always been very tiny, and then, as tools and devkits are pubspread, it gets crowded by both cool and "less" cool people. From my view, the l33t scene core could be more liberal, and the newbies could be more thoughtful and thankful. I personally don’t think of the usual dcemulation.com visitor as a "scener", but rather of someone who wants to play SNES games for free on his telly. No offense, there are also smart and helpful people on there, but the majority gives a shit about how it all works. Then again, this has always been this way. '''B00B: What is your view on the other new super consoles and the possibilitys of hobbyist development on them ie gba etc?''' Emanuel: GBA I actively do development on, but I have not announced anything yet ;-). Jeff Frohwein produced a wonderful coding cable, and I managed to get one. '''B00B: May i say thank you for your time and good luck with your project on behalf of Boob Dreamcast Research and the rest of the emulation scene. ''' Emanuel: thanks 3eaeb38eec3765a666719309fe8aacf6cd3fa725 Ken Friece 0 809 2285 1954 2023-03-02T05:41:32Z Unknown user 0 wikitext text/x-wiki Ken Friece was a Dreamcast developer. He started developing [[NesterDC]] together with [[Takayama Fumihiko]]. When version 3.0 of NesterDC was released, Takayama took over the project and Ken retired from the project. ==Links== *[http://nesterdc.emulation64.com Ken's NesterDC-Website] ==Interview with Ken Friece== '''DCEmulation: So, Ken where are you from and how old are you?''' Ken Friece: I am 24 and originally from Columbus, OH. My current job took me to the Washington DC area, where I have been for the past year. '''DCEmulation: How long have you been programming?''' Ken Friece: I started programming around 3 years ago, and have been hooked ever since. :) '''DCEmulation:''' Currently, you have gotten a good grasp of Dan Potter's libdream, but what did you start off programming with (pc and tools) when you first started to seriously program as a hobby?''' Ken Friece: I started programming in C++ using g++ in a unix environment, doing college programming assignments. Most of the programming that I have done has been in unix, linux, or cygwin, using C or C++. '''DCEmulation: What past projects have you done? (hobby projects)''' Ken Friece: Nothing major. I wrote a Yahtzee game in java to learn the language. Other than that, the most challenging thing that I did was code a simple compiler in C for a college project. '''DCEmulation: What are you working on next with NesterDC? Do you have any other projects in the works? :)''' Ken Friece: Sound will be my number one priority in version3. Another possible improvement is a better user interface. I have received many emails from people about how difficult it is to navigate through the game selecton menu with 1000+ games. I really don't understand why people have that many games, considering only a handful of them are GOOD!!! Although I haven't started another project yet, a few other ports have been getting some serious thought lately. '''DCEmulation: When did you come up for the idea for NesterDC?''' Ken Friece: I stumbled upon Dan Potters site and compiled ghetto pong. The idea of programming for a console was awesome. I started to change things around in ghetto pong, and was also looking at the source code to nester. That's when the idea came to me. The Dreamcast already had ngine-snes9x, sintendo, and DreamSNES, so another SNES emu would be pointless. I knew that I could port nester from looking at ghetto pong source, libdream examples, and nester source. I looked at the source code from many emulators, and nester seemed to be one of the most well organized and coded. '''DCEmulation: After your last release, I've been salivating. When might the next release be?''' Ken Friece: If I told you then I would have to kill you :) Just kidding, I don't even know when the next release will be. Giving a date will just disappoint people if I can't make it, and add stress to the project. Remember, NesterDC is a hobby. '''DCEmulation: Ken, when did you get into the DC Emulation scene and what do you think about it?''' Ken Friece: I got into the DC Emulation scene around 7 months ago, and have enjoyed every minute of it. Its great to see a new project pop up, and existing projects improve. 10434f31fb85c971e1d445dd873e97b7cb185c49 Digimine 0 1074 2286 2023-03-02T05:42:52Z Unknown user 0 Created page with "A minesweeper clone. http://dcemulation.com/dl/dl.php3?url=files/software/digimine_t.zip" wikitext text/x-wiki A minesweeper clone. http://dcemulation.com/dl/dl.php3?url=files/software/digimine_t.zip 673758b113305050a48686bc1968fcd042abd38f DCPaint 0 1075 2287 2023-03-02T05:43:47Z Unknown user 0 Created page with "Dream Paint v0.01 ----------------- Changes (since the first unnumbered release) ------- *Added a simple GUI (borrowed from DCDraw by Tom Waters) *Made a cursor you can actua..." wikitext text/x-wiki Dream Paint v0.01 ----------------- Changes (since the first unnumbered release) ------- *Added a simple GUI (borrowed from DCDraw by Tom Waters) *Made a cursor you can actually see. *Added choice of line thickness. *Fixed some bugs. Known bugs ---------- *Quit in the GUI doesn't work right (just press the side mouse button instead) *Drawing with a thick line on right side of screen draws over the GUI Credits ------- *Dan Potter for LibDream - http://dcdev.allusion.net *Tom Waters for DCDraw - http://members.tripod.co.uk/tom_waters/dreamcast *Jules for getting me started - http://newbie.julesdcdev.com *DCEmulation - http://www.dcemulation.org *Andrew Kieschnick - http://dcload.julesdcdev.com/ *Marcus Comstedt - http://mc.pp.se/dc/ All the developers and everyone else helping to keep the "Dream" alive. David Persik dpersik@hotmail.com 525bef1ed238d43d408a3fd551b87207db44e9ac DC Movie Player 0 1076 2288 2023-03-02T05:45:18Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=DC Movie Player| homepage=[http://www.geocities.co.jp/Playtown/2004/dcdev/dcmplay.html/ DC Movie Player]| price=free| version=Test 2..." wikitext text/x-wiki {{Infobox_Dev_Information| name=DC Movie Player| homepage=[http://www.geocities.co.jp/Playtown/2004/dcdev/dcmplay.html/ DC Movie Player]| price=free| version=Test 2| downloads=[http://geocities.com/dcdev2003/download.html Offsite Link] | release date=5/5/2003| author=[[Bero]]| isactive=No }} DC Movie Player is a video player developed by [[Bero]]. It is based on ffmpeg, with mpeg audio decoding performed by mpglib with a custom dct64 function optimized for the Hitachi SH-4 cpu in the Dreamcast. It supports many container formats and audio/video codecs, but it unfortunately does not contain audio/video synchronization code and is light on features. Despite the lack a/v synch and the small number of features (only ''Play'' is supported), the sheer number of formats and codecs supported and the picture quality make this a rather impressive player. Sadly, development on this player appears to have stopped shortly after the release of the second test version in 2003. (The remainder of the information on this page comes directly from Bero's DC Movie Player homepage) You can discuss about DC Movie Player in the [http://dcemulation.org/phpBB/viewtopic.php?f=40&t=32745 official release thread in our forums]. = Features = *Supports many video/audio format *Autodetects DATA CD or VCD/SVCD *Supports long filename and includes Japanese KANJI *Play only now. no seek, forward, backword, pause, frame skip, audio/video sync etc. *NOTE: This is test release. = Usage = *Boot CD *Press START while loading if your display is PAL *Change CD and push Y button *Select file or VCD track *Push A button *While playing movie, push A to play next file/track, START to back to file menu. = Supported Formats = *format: mpg/avi/asf(wmv)/mov(QuickTime)/rm(RealAudio/Video)/wav/mp3/ogg/ogm *video : mpeg1/mpeg2/mpeg4(DIVX4/5,XviD)/msmpeg v1/v2/v3(DIVX3) *audio : mp1/mp2/mp3/oggvorbis/wma/pcm/various adpcm For more information on supported codecs and container formats, see [http://ffmpeg.mplayerhq.hu/general.html#SEC3 ffmpeg Supported File Formats and Codecs] 98c91afc2e8f391649b432a3666bf87d577814c5 File:Dcplaya1.jpg 6 1077 2289 2023-03-02T05:46:30Z Unknown user 0 wikitext text/x-wiki Dcplaya1 012701a19a7e231d532b1f6bcef84fc23a038158 File:Dcplaya2.jpg 6 1078 2290 2023-03-02T05:46:51Z Unknown user 0 wikitext text/x-wiki Dcplaya2 ec2739668e4e174eacff8386e246ba4f8b3bd021 DCPlaya 0 1079 2291 2023-03-02T05:46:56Z Unknown user 0 Created page with "__NOTOC__ {{Infobox_Dev_Information| name=DCPlaya| image=[[Image:dcplaya1.jpg|250px]]| homepage=[http://sashipa.ben.free.fr/dcplaya/ Homepage]| price=free| version..." wikitext text/x-wiki __NOTOC__ {{Infobox_Dev_Information| name=DCPlaya| image=[[Image:dcplaya1.jpg|250px]]| homepage=[http://sashipa.ben.free.fr/dcplaya/ Homepage]| price=free| version=2.0 beta| downloads=[http://downloads.sourceforge.net/dcplaya/dcplaya-2.0-beta2-files.zip?modtime=1101071458&big_mirror=0 V.2.0 Beta]<br />[http://downloads.sourceforge.net/dcplaya/dcplaya-1.2-discjuggler.zip?modtime=1063152000&big_mirror=0 1.2-stable (DiscJuggler)]<br />[http://downloads.sourceforge.net/dcplaya/dcplaya-1.2-nero.zip?modtime=1063152000&big_mirror=0 1.2-beta (Nero)]<br />[http://downloads.sourceforge.net/dcplaya/dcplaya-1.2.sbi?modtime=1064880000&big_mirror=0 1.2-stable (SBI)] | release date=11/21/2004| author=[[Benjamin Gerard]] and<br /> [[zigziggy]] (Vincent Penne)| isactive=No }} [[Image:dcplaya2.jpg|right|250px|thumb|DCPlaya playing music]] DCPlaya is without any doubt one the best multimedia players for Sega Dreamcast. DCPlaya is more than a simple music player. It is a full [http://en.wikipedia.org/wiki/Lua_%28programming_language%29 LUA development enviroment] and nearly an operating system. Simple DCPlaya users do not need to understand everything on the DCPlaya operating system. This player is also featured on the [http://www.dreamcast-scene.com/index.php/Main/Scenedicate Scenedicate] diskmag. You can discuss about DCPlaya in the [http://dcemulation.org/phpBB/viewtopic.php?t=53370 official release thread on our forums]. ---- ===Supported Formats:=== * FLV (YouTube videos) * MP3 * Ogg-Vorbis * MOD * S3M * NSF * SID Music * SC68 * Audio CD * ...and a lot more. Please help us completing this list. ===Authors=== Benjamin Gerard * ben AT sashipa.com Vincent Penne ([[zigziggy]]) * ziggy AT sashipa.com ==Reporting Bugs== Send an email to 'dcplaya_bugs AT sashipa.com'. Do not forget to add the version number. You can find it in the RELEASE.txt file in the dcplaya CD. ==Website and discussion== '''SourceForge site''' ** http://sourceforge.net/projects/dcplaya '''Official Website:''' ** http://sashipa.ben.free.fr/dcplaya/ '''DCEmulation Forums:''' ** http://dcemulation.org/phpBB/viewtopic.php?t=53370 '''LUA (the programming language of DCPlaya) at Wikipedia:''' ** http://en.wikipedia.org/wiki/Lua_%28programming_language%29 fa0e759ff496d3a7038071eaf1bd5d6841b6be6b DCDivX 0 1080 2292 2023-03-02T05:48:45Z Unknown user 0 Created page with "= About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Develo..." wikitext text/x-wiki = About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[http://www.dcemulation.org/files/software/dcdivx.zip Plain Files] |No |ZIP |966kb |Beta 4 (Includes GPL Source Code) |- |[http://www.dcemulation.org/files/software/dcdivx_b4_dj.zip Disc Juggler] |Yes |ZIP |352kb |Beta 4 (Includes GPL Source Code) |- |[http://www.dcemulation.org/files/software/dcdivx_b4_nero.zip Nero] |Yes |ZIP |352kb |Beta 4 (Includes GPL Source Code) |- |Old Versions |- |[http://www.dcemulation.org/files/software/dcdivxb1.zip Plain Files] |No |ZIP |926kb |Beta 1 (Includes GPL Source Code) |- |[http://www.dcemulation.org/files/software/dcdivxb1DJ.zip Disc Juggler] |Yes |ZIP |288kb |Beta 1 |- |[http://www.dcemulation.org/files/software/dcdivxb1Nero.zip Nero] |Yes |ZIP |288kb |Beta 1 |- |[http://www.dcemulation.org/files/software/dcdivx.zip Plain Files] |No |ZIP |1.6mb |Alpha 3(Includes GPL Source Code) |- |[http://www.dcemulation.org/files/software/dcdivx_dj_a3.zip Disc Juggler] |Yes |ZIP |162kb |Alpha 3 (*Update* Fixes CD Burner Issues) |- |[http://www.dcemulation.org/files/software/dcdivx_nero_a3.zip Nero] |Yes |ZIP |161kb |Alpha 3 (*Update* Fixes CD Burner Issues) |- |Tools |- |[http://www.dcemulation.org/files/software/VirtualDub.zip VirtualDub] |No |ZIP |700kb |Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. |- |[http://www.dcemulation.org/files/software/DivX412Codec.exe DivX Codecs] |No |ZIP |1.5mb |These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. |- |[http://dcemulation.org/files/software/divxDC.vcf VDDivxDC.vcf] |No |ZIP |1.12kb |This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. |} = Need Help Encoding DivX? = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] [http://www.dcemulation.org/chat.htm Chat with others about this sofware] [http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] [http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info ( Check Readme File First!! ) = [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. a0b0dfa28f9d0c0c5a4e3dea1aac55b4450b98af JPamp3 0 1081 2293 2023-03-02T05:49:00Z Unknown user 0 Created page with "{| |- {{Infobox_Dev_Information| name=JPamp3| homepage=[http://website.lineone.net/%7Ejpatkinson/dreamcast/jpamp3.html Homepage]| version=1.1| downloads=[http://www.dcemul..." wikitext text/x-wiki {| |- {{Infobox_Dev_Information| name=JPamp3| homepage=[http://website.lineone.net/%7Ejpatkinson/dreamcast/jpamp3.html Homepage]| version=1.1| downloads=[http://www.dcemulation.org/files/software/jpamp3.zip Plain Files]| release date=09/19/2001| author=Josh| isactive=Yes }} JPAMP3 allows you to play MPEG1 layer3 (MP3) files stored on a PC Hard Disk through your Dreamcast via the Broadband Adaptor. It has been tested with Bladeenc, Lame, and MusicMatch encoded files. MPEG2 and MPEG2.5 are also supported, though untested. = Burning Info = ( Check Readme File First!! ) JPAMP3 SETUP GUIDE # Extract files from Jpamp3 directory on JPAMP3 floppy disc on to hard disk. # Boot Dreamcast with JPAMP3 CD. Obtain the MAC address of the Dreamcast (6 hex numbers on screen). # Edit the runmp3.bat file. Change the MAC address and IP addresses in the file. # Edit the jpamp3.cfg file. Change the pathname to your default path. Can include drive letters eg D:\MP3 # Execute runmp3.bat. Dreamcast should auto boot. c05a5cca9c6369a4f86ff6ed68c60309cb2aa4cc File:DCLinux2.jpg 6 1082 2294 2023-03-02T05:50:00Z Unknown user 0 wikitext text/x-wiki DCLinux2 98768ebedf5a9cba7fd2cd336817b129d6c87c19 File:DCLinux1.jpg 6 1083 2295 2023-03-02T05:50:06Z Unknown user 0 wikitext text/x-wiki DCLinux1 cc8ff62ac6a3ad2f629fb9a24e2d78ae7d144cf9 LinuxDC 0 1084 2296 2023-03-02T05:50:25Z Unknown user 0 Created page with "= About DC Linux = [[Image:DCLinux1.jpg|thumb]] [[Image:DCLinux2.jpg|thumb]] {| |- |Developer: |[http://linuxdc.sf.net/ LinuxDC] (old version--new version [http://www.m17n.org..." wikitext text/x-wiki = About DC Linux = [[Image:DCLinux1.jpg|thumb]] [[Image:DCLinux2.jpg|thumb]] {| |- |Developer: |[http://linuxdc.sf.net/ LinuxDC] (old version--new version [http://www.m17n.org/linux-sh/dreamcast/ here]) |- |Version: |Unknown |- |Last Updated: |06/20/01 |- |Description: |Get the power of Linux on your Dreamcast without having to worry about illegal issues of running software for it as well. This version comes with Mame and Doom ports. Very slow. |- |Status: |Gui now and text based, xwindows also. |} Linux DC is a port of the powerful Linux operating system to the Dreamcast. The newest versions have a GUI and can also be used by an average user. The Linux distribution for the Dreamcast includes XMAME and a port of prBoom (Doom) and can also be used to develop new applications for Dreamcast Linux. LinuxDC includes drivers for the broadband/LAN adpter. A keyboard and a mouse are needed. = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[http://www.fivemouse.com/dclinux/dclinux-010605-dj.zip Disk Juggler] |YES |ZIP |96mb |Thanks to Adrian O'Grady at fivemouse.com |- |[ftp://ftp.m17n.org/pub/super-h/dreamcast/dreamcast-linux-010605.tar.bz2 Plain Files] |No |RAR |75mb |- |Old Version |- |[http://www.dcemulation.com/dl/dl.php3?url=files/software/Linux.rar Nero] |Yes |RAR |9.9mb |- |[http://www.dcemulation.com/dl/dl.php3?url=files/software/linuxdcdj.zip Disk Juggler] |Yes |ZIP |9.7mb |} = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.com/covers Get Covers Here!] = Burning Info = ( Check Readme File First!! ) [http://dcemulation.com/legacy/help/dclinux_guide_for_dj.htm DCLinux Burning Guide DJ] 530af1744b939be07846c63c3be35e7e2fb43713 Turrican2K 0 1085 2297 2023-03-02T06:05:52Z Unknown user 0 Created page with "Turrican2K was a Dreamcast programmer. He released a [[Bomberman Clone]] with [[crt0]]. He released a Dreamcast [[demoscene]] demo called [[Genesis]] as part of the DCAnth..." wikitext text/x-wiki Turrican2K was a Dreamcast programmer. He released a [[Bomberman Clone]] with [[crt0]]. He released a Dreamcast [[demoscene]] demo called [[Genesis]] as part of the [[DCAnthology]] compilation CD under the demo group [[Katharsys]]. He also released a horizontal shooter called [[Project Katana]]. b2e9ac5c770e23a530b241baed2e5cda5958cc68 VMU games 0 148 2298 1598 2023-03-02T06:07:31Z Unknown user 0 wikitext text/x-wiki https://bswirl.kitsunet.org/vmu/game/<br> https://www.sega-dreamcast.com/specials/Dreamcast_VMU-MiniGames-Apps.htm Bad links, need to recover from archive: All links are direct downloads and in .zip format unless otherwise noted. *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Alien%20Shooter.zip Alien Shooter] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Animation%20Test.zip Animation Test] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Basketball.zip Basketball] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Bounce.zip Bounce] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Bowling.zip Bowling] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Boxing.zip Boxing] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Dice.zip Dice] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/dosvms_exe.zip dosvms_exe] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Dream%20Racer.zip Dream Racer] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Emucult.zip Emucult] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Football.zip Football] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Freak%20Skater.zip Freak Skater] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Frog.zip Frog] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Guess%20That%20Square.zip Guess That Square] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Jim%20Light.zip Jim Light] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Jims%20Bowling.zip Jims Bowling] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Jojo%27s%20Problem.zip Jojo's Problem] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Killer%20Mall.zip Killer Mall] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/killer%20Handyman.zip killer Handyman] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Lightsaber.zip Lightsaber] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Magic%208-Ball.zip Magic 8-Ball] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/mega%20man.LCD mega man (LCD)] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Metal%20Gear.zip Metal Gear] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Mini%20Racer.zip Mini Racer] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Muddy%20Says.zip Muddy Says] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Puzzle.zip Puzzle] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Quicktime%20Event.zip Quicktime Event] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Rainbow%206.zip Rainbow 6] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/resident%20evil.LCD resident evil (LCD)] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Revenge.zip Revenge] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Roadkill.zip Roadkill] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/SCALIBUR2_U_VM.zip SCALIBUR2_U_VM] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Sample.zip Sample] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Scroll.zip Scroll] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Shell%20Game.zip Shell Game] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Simon.zip Simon] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Sketch.zip Sketch] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Sniper.zip Sniper] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Star%20Wars.zip Star Wars] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Supercross.zip Supercross] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Tetris.zip Tetris] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/tetris.vms tetris (VMS)] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Time%20Crisis.zip Time Crisis] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Time%20Shooter.zip Time Shooter] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Until%20Death.zip Until Death] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/Virtual%20Teacher.zip Virtual Teacher] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/VMU%20Adventure.zip VMU Adventure] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/VMU%20Fighter.zip VMU Fighter] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/VMU%20Racer.zip VMU Racer] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/VMUV%20Player%20001.vms VMUV Player 001 (VMS)] *[http://dcemulation.org/covers/index.cgi?get&Vmu%20Games/ZOMBIE_U__VM.zip ZOMBIE_U__VM (BIN)] {{DCWiki:Stub}} c1b05a57d22ee1c32c62bd270082b8fdc71bc983 File:GEE-covers p.png 6 1088 2299 2023-03-02T06:09:51Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=GEE-covers p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} fe3c9685a157917e00d0e29714bfab358092dbec File:Scenedicate1-01 p.png 6 1086 2300 2023-03-02T06:09:51Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Scenedicate1-01 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7c53f80e7f5babbf961ebe75b74a466dad30b9ea File:Scenedicate1-02 p.png 6 1087 2301 2023-03-02T06:09:51Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Scenedicate1-02 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 72bb2a6ec9473247f46db50b45bf39fdd620111e File:Scenedicate01 p.gif 6 1089 2302 2023-03-02T06:10:31Z Unknown user 0 wikitext text/x-wiki Scenedicate01 p 83258337197d755e67c47b4b9ab659a42caae089 Scenedicate 0 1090 2303 2023-03-02T06:10:35Z Unknown user 0 Created page with "[[Image:Scenedicate01_p.gif|200px|Scenedicate Logo]] ==General== Scenedicate was the world's first Dreamcast diskmag, with interviews, artwork (analog and digital), and playa..." wikitext text/x-wiki [[Image:Scenedicate01_p.gif|200px|Scenedicate Logo]] ==General== Scenedicate was the world's first Dreamcast diskmag, with interviews, artwork (analog and digital), and playable programs right on the disc. Alongside the free download, scenedicate is also available on the DVD-ROM of the December issue of the prestigious German videogame/lifestyle magazine GEE (Games Entertainment Education). Scenedicate is also featured in an article in the print section of the magazine. [[Image:GEE-covers_p.png|200px|GEE Magazine]] Website: [http://www.geemag.de www.geemag.de] ==Contents== [[Image:Scenedicate1-01_p.png|250px|Menu]] [[Image:Scenedicate1-02_p.png|250px|Menu]] ===Issue #1=== * Introduction * Restoring Used Games * Need for console only parties (includes statements from Psychad / organizer of the Deadline Console party in Stockholm) * [[ScummVM]] ** ScummVM interview with _sev and joostp (coders) ** Inherit the Earth interview (including demoversion) ** ScummVM 0.8.0 (latest version for Dreamcast) * GamePark 32 ** GamePark 32, the developer's handheld! (article by Optimus) ** GP32 demoscene, where is it? (article by Optimus) * [[DCPlaya]] (version 2.0 beta) * The story behind SHizZLE (statements from Lupin of Team Pokéme) * Capitalism influence in free culture (article by ps) * Scene demos (demos which can be run right off) ** Hex Pistols ** Jenny Thinks ** One Day Miracle * 8- and 16-Bit videogame charts * Credits ===Promotion=== Beside the artice in the print part of the GEE, the Dreamcast-Scene website also promoted scenedicate at the 2005 edition of [http://web.archive.org/web/20080304094115/2007.tum-party.net/ The Ultimate Meeting]. ==Downloads== You now can download the final release of Scenedicate #1, and burn it to a CDR using [[BootDreams]], CDRecord, Alcohol 120%, or DiscJuggler. *Mirrors: **[http://dcevolution.net/downloads/hosted/scenedicate01.zip DCEvolution.net] **[http://www.megaupload.com/de/?d=GU02T7F8 MegaUpload.de] **[http://www.dreamcast-scene.com/downloads/scenedicate01.zip Dreamcast-Scene.com] 6ad9c83fe3f7bdd1457c0f92637e13d8063f476b Ss teven 0 1091 2304 2023-03-02T06:12:38Z Unknown user 0 Created page with "This interview was taken in 2001 by Wraggster. '''DCEmulation.com: So what made you you decide to work on a emulator for the Sega Mastersystem?''' SS_teven: Mainly because a..." wikitext text/x-wiki This interview was taken in 2001 by Wraggster. '''DCEmulation.com: So what made you you decide to work on a emulator for the Sega Mastersystem?''' SS_teven: Mainly because at the time, when I started to begin development, there wasnt any Master System emulators out. DreamSMS was out, but that only supported Game Gear. And since I remember playing Road Rash and Sonic I thought it would be a good system to emulate. '''DCEmulation.com: How long have you spent working on this project?''' SS_teven: I'd probably say about 6 hours a day for the past 2 months. (I'm a little slow ;) heh, long nights here and there ' '''DCEmulation.com: How long have you been involved in the dreamcast scene?'' SS_teven: I actually only got my Dreamcast to start programming, (call me a freak if u will ;) and that was back in May 2001. '''DCEmulation.com: I'm interested, what is the future of sms plus?''' SS_teven: At the moment, the future looks pretty good. I have heaps of new ideas to put in SMS Plus! '''DCEmulation.com: Care to give away some of your ideas?''' SS_teven: Not at this moment, as they are just 'ideas', and i am still deciding weither to put these features in or not. '''DCEmulation.com: What problems have you had and how did you overcome them?''' SS_teven: The main problems I've encountered are speed. The DC is a powerful machine and has some complex operations, and plus Ive only just started out programming, so im new at this :P I have overcome speed in the past week, the main thing was my bitmap was set to 16bit, not 8bit, which slowed it down by 30fps. Sound is probably the hardest part of the DC that one would encouter, and i still havnt overcome this yet, current beta has heaps of sound bugs, but it works. '''DCEmulation.com: When this project is done do u you see yourself working on any other emu's or possibly porting an open source game?''' SS_teven: Im not quite sure about games, but i wouldnt mind starting another emulator. Gameboy and Commodore 64 are two things that pop in my mind ;) '''DCEmulation.com: Thank you for your time SS_teven''' SS_teven: Thanks :D, nice talking to you 9277830acc689e9f4b9d0005a2499175ab8548e4 File:Variance 1.jpg 6 1092 2305 2023-03-02T06:13:27Z Unknown user 0 wikitext text/x-wiki Variance 1 d8c2e59800d0a88285533655c4ec512417a0a566 Variance 0 1093 2306 2023-03-02T06:13:31Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Variance |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Variance |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Variance_1.jpg|thumb| Variance]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://haujobb.scene.org/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/hjb_vpal.zip DiscJuggler] (PAL)}}} |- style="background:#ffffff" |Release Date || {{{release date|April, 2001}}} |- style="background:#ffffff" |Author || {{{author|[http://haujobb.scene.org/ haujobb]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Variance, by the German demo group haujobb, was the first huge demo for the Dreamcast. It was released in April 2001 at the Mekka & Symposium demo-party in Fallingbostel in Northern Germany, and won the console competition right next to PlayStation & GameBoy demos. Unfortunately, this demo 'only' runs on PAL machines, and graphical glitches will appear on NTSC Dreamcasts. ===Team Credits=== * Fuzzel * Acryl * Raytrayza * Nomad * Amoc * Hellfire ==Downloads== * Dreamcast (PAL) ** Local - [http://dcemulation.org/1-newsdump/games-demos/hjb_vpal.zip CDI] - 04/''??''/2001 ==Links== * [http://dcevolution.sourceforge.net/index.php?id=variance DCEvolution] Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=2415 Pouet.net] Page * [http://haujobb.scene.org/ Haujobb] Website 749ab772459328767905fd06d36e32397575d47d 2307 2306 2023-03-02T06:13:40Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Variance |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Variance_1.jpg|thumb| Variance]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://haujobb.scene.org/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/hjb_vpal.zip DiscJuggler] (PAL)}}} |- style="background:#ffffff" |Release Date || {{{release date|April, 2001}}} |- style="background:#ffffff" |Author || {{{author|[http://haujobb.scene.org/ haujobb]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Variance, by the German demo group haujobb, was the first huge demo for the Dreamcast. It was released in April 2001 at the Mekka & Symposium demo-party in Fallingbostel in Northern Germany, and won the console competition right next to PlayStation & GameBoy demos. Unfortunately, this demo 'only' runs on PAL machines, and graphical glitches will appear on NTSC Dreamcasts. ===Team Credits=== * Fuzzel * Acryl * Raytrayza * Nomad * Amoc * Hellfire ==Downloads== * Dreamcast (PAL) ** Local - [http://dcemulation.org/1-newsdump/games-demos/hjb_vpal.zip CDI] - 04/''??''/2001 ==Links== * [http://dcevolution.sourceforge.net/index.php?id=variance DCEvolution] Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=2415 Pouet.net] Page * [http://haujobb.scene.org/ Haujobb] Website 135eec5c93e242314074b73eb451f6a9483bbc46 File:Chrysler 1.png 6 1094 2308 2023-03-02T06:14:39Z Unknown user 0 wikitext text/x-wiki Chrysler 1 fe43263b58c57932b0d3e70408df116bd6228b5a Chrysler 0 1095 2309 2023-03-02T06:14:41Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Chrysler |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Chrysler |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Chrysler_1.png|thumb|300px| Chrysler Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Fit]/<br/>[http://web.archive.org/web/20060821030947/http://bandwagon.doesntexist.com/ Bandwagon]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/chrysler/chrysler_dc.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/chrysler/chrysrc.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/06/2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]/<br/>Bandwagon}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Demo groups 'Fit', and 'Bandwagon', ported their open source demo 'Chrysler', which is also available for Amiga, GP32, Linux and others, to the Dreamcast. Happy watching! ==Downloads== * 1st - [http://dcemulation.org/1-newsdump/games-demos/chrysler/chrysler_dc.zip Plain Files] - 06/06/2005 * Latest - [http://dcemulation.org/1-newsdump/games-demos/chrysler/chrysrc.zip Source] - 04/04/2009 ==Links== * [http://www.dcevolution.net/index.php?id=chrysler DCEvolution]: Hosted DiscJuggler Image * [http://pouet.net/prod.php?which=12391 Pouet]: Demo Page 9a15c3dfee5ebbae86c0547200b538ce1a66eee9 File:Delic 1.jpg 6 1096 2310 2023-03-02T06:15:52Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Delic 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 6fd751c8371428939757058d8ca07cc4032c2c10 File:Delic 3.jpg 6 1097 2311 2023-03-02T06:15:52Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Delic 3}} |date=2023-03-03 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 54d481713b6f7f4dd9565a9080b4cc37cca42eb5 File:Delic 2.jpg 6 1098 2312 2023-03-02T06:15:52Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Delic 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 657e1bd69e6d61045477ac40152dac8b9269d17a File:Delic 4.jpg 6 1099 2313 2023-03-02T06:15:52Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Delic 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} fa5481c5dba6662e33a7bc17aff54544840646d2 Delicious 0 1100 2314 2023-03-02T06:16:06Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Delicious |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Delicious |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Delic_1.jpg|center|280px|thumb| Delicious Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://yodel.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Only}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/ydl_deli.zip DiscJuggler]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/05/2001}}} |- style="background:#ffffff" |Author || {{{author|[[#Project Team|Below]]}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Delicious by Yodel is a demo for the Dreamcast which was released at 2001-08-05 at the Assembly demoparty in Finland. It won the console competition. [[Image:Delic_2.jpg|center|250px| Delicious Demo]] [[Image:Delic_3.jpg|center|250px| Delicious Demo]] [[Image:Delic_4.jpg|center|250px| Delicious Demo]] ===Project Team=== * Snooky (Karl-Anders Johansson) - Code * Ayla (Andreas Alptun) - Code * Voodoo (Mikael Persson) - Code * Spiff (Paul Blomdahl) - Graphics / 3D modeling * Alces (Staffan Lincoln) - 3D modeling * O.B.M (Mike Wells) - Cartoons * Eyas (Ludvig Linge) - Music Delicious is one of the best Dreamcast demos out there. ==Downloads== * Demo - [http://dcemulation.org/1-newsdump/games-demos/ydl_deli.zip DiscJuggler] ==Links== [http://www.youtube.com/watch?v=uybHZxvGHgc Video] e9b6c0d51095e23d1647a0efd24456c896f95aa8 File:HexPistol 1.png 6 1101 2315 2023-03-02T06:16:41Z Unknown user 0 wikitext text/x-wiki HexPistol 1 8cb71c780841674c066314f376630e33af86e4f8 Hex Pistols 0 1102 2316 2023-03-02T06:16:43Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hex Pistols |- border="0" cellpadding="2" cellspacing="..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hex Pistols |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:HexPistol_1.png|thumb|300px| Hex Pistols Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_dc.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/06/2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Finnish demo group 'Fit' ported their open source demo 'Hex Pistols', which is also available for Amiga, GP32, Linux and others, to the Dreamcast. Happy watching! ==Downloads== * 1st - [http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_dc.zip Plain Files] - 06/06/2005 * 1st - [http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_src.zip Source] - 05/23/2005 ==Links== * [http://www.dcevolution.net/index.php?id=hex_pistols DCEvolution]: Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=17311&howmanycomments=-1 Pouet]: Demo Page 1a306e445a671a28e4a50628b596a55a6e796eaf 2317 2316 2023-03-02T06:16:54Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hex Pistols |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:HexPistol_1.png|thumb|300px| Hex Pistols Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_dc.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/06/2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Finnish demo group 'Fit' ported their open source demo 'Hex Pistols', which is also available for Amiga, GP32, Linux and others, to the Dreamcast. Happy watching! ==Downloads== * 1st - [http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_dc.zip Plain Files] - 06/06/2005 * 1st - [http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_src.zip Source] - 05/23/2005 ==Links== * [http://www.dcevolution.net/index.php?id=hex_pistols DCEvolution]: Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=17311&howmanycomments=-1 Pouet]: Demo Page c81941de53afd7990a0e968e4c44b6c3ca374d86 File:JapAm.jpg 6 1103 2318 2023-03-02T06:17:41Z Unknown user 0 wikitext text/x-wiki JapAm df1eb1690ae5f18cc23747431392d479a50be27a JapAmerica 0 1104 2319 2023-03-02T06:17:44Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JapAmerica |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JapAmerica |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:JapAm.jpg|thumb|center|280px| JapAmerica]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://atomicbits.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|#1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dcemulation.com/dl/dl.php3?url=files/software/Dragon.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/10/2002}}} |- style="background:#ffffff" |Author || {{{author|Dragonsimoto}}} |- style="background:#ffffff" |Type of game || {{{type|Interactive<br/> Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== A tech demo. Submitted as an entry for the 2002 programming contest. '''''Quote via Author:<br/> '' 'This is my dumb demo for the contest at Dcemulation*. ''I am proud to say this is my FIRST semi complete project for the Dreamcast or anything for that matter. ''I am still learning alot!!! ''I have been coding since 2/?/02, so you can see this is a learning process. ''I wanted to make the top 50% but I doubt I get that high :(.' ===Controls=== * D-Pad → Cube(s) rotation * Y → Alpha Blending * X → Scoll thru the Demo Textures * Start → Quit ==Downloads== * [http://www.dcemulation.com/dl/dl.php3?url=files/software/Dragon.zip Plain Files] * [http://www.dcemulation.com/dl/dl.php3?url=files/software/DragonNero.zip Nero] * [http://www.dcemulation.com/dl/dl.php3?url=files/software/DragonCDI.zip DiscJuggler] 2bfcdb7f0ccd89061500612408cdcaa6f1b375af 2320 2319 2023-03-02T06:17:50Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JapAmerica |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:JapAm.jpg|thumb|center|280px| JapAmerica]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://atomicbits.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|#1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dcemulation.com/dl/dl.php3?url=files/software/Dragon.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/10/2002}}} |- style="background:#ffffff" |Author || {{{author|Dragonsimoto}}} |- style="background:#ffffff" |Type of game || {{{type|Interactive<br/> Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== A tech demo. Submitted as an entry for the 2002 programming contest. '''''Quote via Author:<br/> '' 'This is my dumb demo for the contest at Dcemulation*. ''I am proud to say this is my FIRST semi complete project for the Dreamcast or anything for that matter. ''I am still learning alot!!! ''I have been coding since 2/?/02, so you can see this is a learning process. ''I wanted to make the top 50% but I doubt I get that high :(.' ===Controls=== * D-Pad → Cube(s) rotation * Y → Alpha Blending * X → Scoll thru the Demo Textures * Start → Quit ==Downloads== * [http://www.dcemulation.com/dl/dl.php3?url=files/software/Dragon.zip Plain Files] * [http://www.dcemulation.com/dl/dl.php3?url=files/software/DragonNero.zip Nero] * [http://www.dcemulation.com/dl/dl.php3?url=files/software/DragonCDI.zip DiscJuggler] d6d5008066cfcd856b8178fe83bf8eea9210b9f1 File:1DayMiracle 2.jpg 6 1105 2321 2023-03-02T06:19:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=One Day Miracle}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 50be86e1fdc2e33e5aa79d49bdf9f059c2ef8f30 File:1DayMiracle 1.jpg 6 1106 2322 2023-03-02T06:19:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=One Day Miracle}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 50be86e1fdc2e33e5aa79d49bdf9f059c2ef8f30 File:1DayMiracle 3.jpg 6 1107 2323 2023-03-02T06:19:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=One Day Miracle}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 50be86e1fdc2e33e5aa79d49bdf9f059c2ef8f30 One Day Miracle 0 1108 2324 2023-03-02T06:19:22Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | One Day Miracle |- border="0" cellpadding="2" cellspaci..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | One Day Miracle |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:1DayMiracle 1.jpg|thumb|320px| .fit.]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/miracle_dc.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|June, 2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The fourth demo by the Finnish demogroup 'Fit' was ported to the Dreamcast in June 2005, but also the one which got the less attention. Originally made for Linux, it was later ported to Amiga PPC, MacOS X, MS-Dos, SGI Irix, and Windows. Released in 2002, for the Assembly demoparty in Helsinki, Finland. It unfortunately only became 14th in the 64k intro compo, and that's the most interesting part. This whole demo is indeed only 64k big but uses the [[SDL]] libraries, which makes the whole packet slightly bigger. Marq, the coder and designer of One Day Miracle, mentioned that it wasn't advertised on a larger scale because he wasn't very satisfied with the port. [[Image:1DayMiracle 2.jpg|320px| Demo Screen 1]] [[Image:1DayMiracle 3.jpg|320px| Demo Screen 2]] ===Credits=== * code, design............... Marq * add. code, win port ..... Pete * music ....................... Roz * thanks ...................... Sam Lantinga, AmurWolf/SoCS ==Downloads== * Local - [http://dcemulation.org/1-newsdump/games-demos/miracle_dc.zip Plain Files] - 06/''??''/2005 * Mirror - [http://ftp.kameli.net/pub/fit/miracle/miracle_dc.zip Plain Files] - 06/''??''/2005 ==Links== * [http://dcevolution.sourceforge.net/index.php?id=one_day_miracle DCEvolution] hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=7196 Pouet.net] Page bc937e41ba0e8e779126e7128690dd6884907e16 DC Anim 0 1109 2325 2023-03-02T06:23:11Z Unknown user 0 Created page with "Developer: John Blanchard Version: 1.0 Last Updated: 11-30-00 This is another tool that lets you edit and create your own VMU animations. The sourcecode is available fo..." wikitext text/x-wiki Developer: John Blanchard Version: 1.0 Last Updated: 11-30-00 This is another tool that lets you edit and create your own VMU animations. The sourcecode is available for DC Anim as well. [http://www.dcemulation.org/files/pcemu/DCAnim.zip ZIP File] [http://www.dcemulation.org/files/pcemu/dcanimcode.zip Source Code] 99d0564d2939a844c0f9c76d5796af8a76000d29 VMU development 0 99 2326 2131 2023-03-02T06:24:35Z Unknown user 0 /* Dream Animator */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' === DC Anim === By developer John Blanchard, Version: 1.0, Last Updated: 11-30-00, [http://www.dcemulation.org/files/pcemu/DCAnim.zip ZIP File], [http://www.dcemulation.org/files/pcemu/dcanimcode.zip Source Code] This is another tool that lets you edit and create your own VMU animations. The sourcecode is available for DC Anim as well. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 1991f0fd35a24eea83705ad169256bc136b7c977 File:Dreamemu-01.jpg 6 1110 2327 2023-03-02T06:28:01Z Unknown user 0 wikitext text/x-wiki Dreamemu-01 5900367fb3dfb3ff80933c82dacce481717f63d0 Dreamcast emulators 0 4 2328 971 2023-03-02T06:28:34Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] ==Other older emulators== These emulators are listed mostly for historical/archival reasons. *[DreamEmu](http://www.dreamemu.net/) *[Dreamer](http://emulatronia.com/dcemu.htm) *Makaron *[Swirly](http://swirly.sourceforge.net/) 51c7835c57718099fa98399ff704a1a82eb19b50 2329 2328 2023-03-02T06:29:09Z Unknown user 0 /* DreamEmu */ wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ==Other older emulators== These emulators are listed mostly for historical/archival reasons. *[DreamEmu](http://www.dreamemu.net/) *[Dreamer](http://emulatronia.com/dcemu.htm) *Makaron *[Swirly](http://swirly.sourceforge.net/) a1926b7f2cefd695c33f88920f38c5aef120688f 2331 2329 2023-03-02T06:30:01Z Unknown user 0 /* Other older emulators */ wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ==Other older emulators== [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] These emulators are listed mostly for historical/archival reasons. *[DreamEmu](http://www.dreamemu.net/) *[Dreamer](http://emulatronia.com/dcemu.htm) *Makaron *[Swirly](http://swirly.sourceforge.net/) c0b5d226d913842123243e7abdf4e0997927beea 2337 2331 2023-03-02T06:35:43Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Chankast== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ==Other older emulators== [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] These emulators are listed mostly for historical/archival reasons. *[DreamEmu](http://www.dreamemu.net/) *[Dreamer](http://emulatronia.com/dcemu.htm) *Makaron *[Swirly](http://swirly.sourceforge.net/) e6b947e2599f3e66b2994e02fde8a05947e67104 2338 2337 2023-03-02T06:37:30Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Chankast== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ==Other older emulators== [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] These emulators are listed mostly for historical/archival reasons. *[DreamEmu](http://www.dreamemu.net/) *[Dreamer](http://emulatronia.com/dcemu.htm) *Makaron *[Swirly](http://swirly.sourceforge.net/) 9d52c900d5a37b8c0d7889eee182ae4bc70c3822 2339 2338 2023-03-02T06:41:23Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Chankast== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ==Other older emulators== ===Makaron=== *Makaron [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] These emulators are listed mostly for historical/archival reasons. ===DreamEmu *[DreamEmu](http://www.dreamemu.net/) ===Dreamer=== *Developed by ElSemi in late 2000 into mid-2001, Dreamer was the first working and released Dreamcast emulator for PC. *Latest version: Alpha 0.25 - Download [http://www.dcemulation.org/files/pcemu/dreamer002.zip v0.02] *[Dreamer](http://emulatronia.com/dcemu.htm) *SH4: All opcodes is emulated (100% have not been proven) interprets. Those of movements of data to memory and jumps are emulated using dynamic recompilación. *FPU: All opcodes emulated for want of the 2 specific instructions of the Dreamcast. > uses the interpreter - Slow. *PowerVR: The basic part of the hardware 2d works (Framebuffer correctly and control registries). It lacks the way of video 555. We are at the moment looking for information on the hardware 3d and display lists. *JoyPad: Emulated completely. *Maple Bus: The control registries have been identified and will be working shortly. *Sound: Nothing yet. *CDROM: Almost emulated. *DEBUGGER: The emulator takes integrated to debugger (that is a little patatero but it plays his role). Executing debugger implies that the execution of the program is much more slow. The handling keys are the following ones: *F5: Go (uninterrupted Execution)<br/> *F7: Draw up Into (to execute entering the subroutines)<br/> *F8: Step Over (To execute without entering the subroutines, does not work to 100%) *Commandos: The commandos are written in the inferior part of the window of the code:<br/> **G (Just as F5)<br/> **G direction (Executes until that direcci¢n. in hex)<br/> **D direction (shows the memory of the specified direction. in hex)<br/> **D registry (it shows the memory of the direction loaded in the chosen registry)<br/> **And direction data (writes in the direction the specified data. 0-FF in hex)<br/> **R registry value (loads the value in the registry. 0-FFFFFFFF in hex)<br/> **S (it stops the single emulation works in Go way)<br/> **F (it draws framebuffer)<br/> **X (to leave)<br/> **Z (reset, cracks, not to use)<br/> **WD 0|1 (oculta|muestra window of data)<br/> **WR 0|1 (oculta|muestra window of registries)<br/> **WM 0|1 (oculta|muestra window of messages)<br/> **WC 0|1 (oculta|muestra code window, nor is happened to you, but where you write) ===Swirly=== *[Swirly](http://swirly.sourceforge.net/) f972f07e076934962a0324a6383d2adf967ce794 2340 2339 2023-03-02T06:41:57Z Unknown user 0 /* Other older emulators */ wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Chankast== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ==DreamEmu== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ==Other older emulators== These emulators are listed mostly for historical/archival reasons. ===Makaron=== *Makaron [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] ===DreamEmu=== *DreamEmu: [http://www.dreamemu.net/] ===Dreamer=== *Developed by ElSemi in late 2000 into mid-2001, Dreamer was the first working and released Dreamcast emulator for PC. *Latest version: Alpha 0.25 - Download [http://www.dcemulation.org/files/pcemu/dreamer002.zip v0.02] *[Dreamer](http://emulatronia.com/dcemu.htm) *SH4: All opcodes is emulated (100% have not been proven) interprets. Those of movements of data to memory and jumps are emulated using dynamic recompilación. *FPU: All opcodes emulated for want of the 2 specific instructions of the Dreamcast. > uses the interpreter - Slow. *PowerVR: The basic part of the hardware 2d works (Framebuffer correctly and control registries). It lacks the way of video 555. We are at the moment looking for information on the hardware 3d and display lists. *JoyPad: Emulated completely. *Maple Bus: The control registries have been identified and will be working shortly. *Sound: Nothing yet. *CDROM: Almost emulated. *DEBUGGER: The emulator takes integrated to debugger (that is a little patatero but it plays his role). Executing debugger implies that the execution of the program is much more slow. The handling keys are the following ones: *F5: Go (uninterrupted Execution)<br/> *F7: Draw up Into (to execute entering the subroutines)<br/> *F8: Step Over (To execute without entering the subroutines, does not work to 100%) *Commandos: The commandos are written in the inferior part of the window of the code:<br/> **G (Just as F5)<br/> **G direction (Executes until that direcci¢n. in hex)<br/> **D direction (shows the memory of the specified direction. in hex)<br/> **D registry (it shows the memory of the direction loaded in the chosen registry)<br/> **And direction data (writes in the direction the specified data. 0-FF in hex)<br/> **R registry value (loads the value in the registry. 0-FFFFFFFF in hex)<br/> **S (it stops the single emulation works in Go way)<br/> **F (it draws framebuffer)<br/> **X (to leave)<br/> **Z (reset, cracks, not to use)<br/> **WD 0|1 (oculta|muestra window of data)<br/> **WR 0|1 (oculta|muestra window of registries)<br/> **WM 0|1 (oculta|muestra window of messages)<br/> **WC 0|1 (oculta|muestra code window, nor is happened to you, but where you write) ===Swirly=== *[Swirly](http://swirly.sourceforge.net/) 719ce57447b835807de9f0a28da45ddcff6a2d1e 2341 2340 2023-03-02T06:43:00Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Other older emulators== These emulators are listed mostly for historical/archival reasons. ===Chankast=== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ===Makaron=== *Makaron [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] ===DreamEmu=== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [http://dcemulation.com/1-newsdump/emulators/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [http://dcemulation.com/1-newsdump/emulators/dreamemu-003.zip v0.03 - 08/03/01], [http://dcemulation.com/1-newsdump/emulators/dreamemu-002.zip v0.02], [http://dcemulation.com/1-newsdump/emulators/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ===Dreamer=== *Developed by ElSemi in late 2000 into mid-2001, Dreamer was the first working and released Dreamcast emulator for PC. *Latest version: Alpha 0.25 - Download [http://www.dcemulation.org/files/pcemu/dreamer002.zip v0.02] *[Dreamer](http://emulatronia.com/dcemu.htm) *SH4: All opcodes is emulated (100% have not been proven) interprets. Those of movements of data to memory and jumps are emulated using dynamic recompilación. *FPU: All opcodes emulated for want of the 2 specific instructions of the Dreamcast. > uses the interpreter - Slow. *PowerVR: The basic part of the hardware 2d works (Framebuffer correctly and control registries). It lacks the way of video 555. We are at the moment looking for information on the hardware 3d and display lists. *JoyPad: Emulated completely. *Maple Bus: The control registries have been identified and will be working shortly. *Sound: Nothing yet. *CDROM: Almost emulated. *DEBUGGER: The emulator takes integrated to debugger (that is a little patatero but it plays his role). Executing debugger implies that the execution of the program is much more slow. The handling keys are the following ones: *F5: Go (uninterrupted Execution)<br/> *F7: Draw up Into (to execute entering the subroutines)<br/> *F8: Step Over (To execute without entering the subroutines, does not work to 100%) *Commandos: The commandos are written in the inferior part of the window of the code:<br/> **G (Just as F5)<br/> **G direction (Executes until that direcci¢n. in hex)<br/> **D direction (shows the memory of the specified direction. in hex)<br/> **D registry (it shows the memory of the direction loaded in the chosen registry)<br/> **And direction data (writes in the direction the specified data. 0-FF in hex)<br/> **R registry value (loads the value in the registry. 0-FFFFFFFF in hex)<br/> **S (it stops the single emulation works in Go way)<br/> **F (it draws framebuffer)<br/> **X (to leave)<br/> **Z (reset, cracks, not to use)<br/> **WD 0|1 (oculta|muestra window of data)<br/> **WR 0|1 (oculta|muestra window of registries)<br/> **WM 0|1 (oculta|muestra window of messages)<br/> **WC 0|1 (oculta|muestra code window, nor is happened to you, but where you write) ===Swirly=== *[Swirly](http://swirly.sourceforge.net/) 4fc2dc38fafe0face0a35b893cf9d85942b8f2dc File:Swirly.jpg 6 1111 2330 2023-03-02T06:29:47Z Unknown user 0 wikitext text/x-wiki Swirly 1bf4f771a0cb586fc98a266e465100413139fd01 File:Aimtank 1.png 6 1113 2332 2023-03-02T06:32:23Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Aimtank 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1f87e9ab1971bc70f97b735351c80fe4a8a2af5c File:Aimtank 2.png 6 1112 2333 2023-03-02T06:32:23Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Aimtank 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c80a634bce5ef57ec0643c70e4ff0bd283877ba8 File:Aimtank 3.png 6 1114 2334 2023-03-02T06:32:23Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Aimtank 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 9d0d74bb19f7e73f02b423771dde2326dbca2287 Template:Infobox Game Information 10 1115 2335 2023-03-02T06:32:44Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|<i>No Screenshot Available</i>}}} |- style="background:#ffffff" |Homepage || {{{homepage|<i>Unknown</i>}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|<i>Unknown</i>}}} |- style="background:#ffffff" |Type of game || {{{type|<i>Unknown</i>}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} e294da276dc174368a957655e6d3b5fb0363b84d Aiming Tank 0 1116 2336 2023-03-02T06:32:52Z Unknown user 0 Created page with "{{Infobox_Game_Information| name=Aiming Tank| image=[[Image:Aimtank_1.png|center|thumb|280px| Screenshot]]| homepage=[http://nagoya.cool.ne.jp/dcdev38/result/aimtank.html H..." wikitext text/x-wiki {{Infobox_Game_Information| name=Aiming Tank| image=[[Image:Aimtank_1.png|center|thumb|280px| Screenshot]]| homepage=[http://nagoya.cool.ne.jp/dcdev38/result/aimtank.html Homepage]| version=Beta 2| downloads=[http://nagoya.cool.ne.jp/dcdev38/files/aimtank0525.zip Plain Files]| release date=05/25/2002| author=''Unknown| type=1-2 Player<br/>Strategy| refreshrate=''Unknown| isactive=No }} Aiming Tank is a 1-2 player strategy shooting game. [[Image:Aimtank_2.png|280px| Aiming Tank]] [[Image:Aimtank_3.png|280px| Aiming Tank]] Destroy your opponent's tank, before he destroys you! ==Downloads== * Beta 2 - [http://nagoya.cool.ne.jp/dcdev38/files/aimtank0525.zip Plain Files] - 05/25/2002 * Beta 1 - [http://nagoya.cool.ne.jp/dcdev38/files/atank0503.zip Plain Files] - 05/03/2002 * Beta 1 - [http://dcemulation.org/1-newsdump/games-demos/aim_tank/AimingTank.sbi SBI] - 05/03/2002 * Beta 1 - [http://nagoya.cool.ne.jp/dcdev38/files/atank0503cdi.zip DiscJuggler] - 05/05/2002 * Beta 1 - [http://nagoya.cool.ne.jp/dcdev38/files/atank0503nrg.zip Nero] - 05/05/2002 * Snapshot - [http://nagoya.cool.ne.jp/dcdev38/files/dc/atank_src_20020803.lzh Source] - 08/03/2002 166fc90aa857c2bfd01b69e0a4f73d1eb3240531 File:Epifighter1.jpg 6 1117 2342 2023-03-02T06:49:09Z Unknown user 0 wikitext text/x-wiki Epifighter1 a14357de9c416f10ce149fd0a20ffefcfb7e07a3 File:Epifighter2.jpg 6 1118 2343 2023-03-02T06:49:17Z Unknown user 0 wikitext text/x-wiki Epifighter2 f91861e1dd6448c558127542d83a9a12115bed33 Epifighter 0 1119 2344 2023-03-02T06:49:22Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Epifighter |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Epifighter |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Epifighter1.jpg|thumb|center|260px| Epifighter]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/*/http://www.epifighter.fr.st/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|''Below}}} |- style="background:#ffffff" |Release Date || {{{release date|2002}}} |- style="background:#ffffff" |Author || {{{author|[http://www.epitech.eu/ Epitech]}}} |- style="background:#ffffff" |Type of game || {{{type|Fighting}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> A game developed by students of the Epitech Game Development Laboratory using the [[Iris3D]] engine. Released in 2002. [[Image:Epifighter2.jpg|thumb|center|300px| Select Screen]] ==Downloads== * Unknown version - [http://dcemulation.org/1-newsdump/games-demos/epitech/Epifighter.zip Plain Files] - 2002 * Unknown version - [http://dcemulation.org/1-newsdump/games-demos/epitech/Epifighter_bO.sbi SBI] - 2002 ==Links== * [http://www.epitech.net/ Official Site] * [http://www.dcevolution.net/index.php?id=epitech_cd Epitech Game Collection] @ DCEvolution 616e50c1f223fb1b6bbfc4175df96a84588fdaad File:CaveStory.png 6 1120 2345 2023-03-02T06:50:01Z Unknown user 0 wikitext text/x-wiki CaveStory e82c4a7875277f283b09fa152f6eb2e13dd045b4 Cave Story 0 1121 2346 2023-03-02T06:50:07Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NXEngine for DC |- border="0" cellpadding="2" cellspaci..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NXEngine for DC |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:CaveStory.png|thumb|300px| Cave Story Menu]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[https://sourceforge.net/p/nxdc/wiki/Home/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[[Cave Story#Downloads|see Downloads section]]}}} |- style="background:#ffffff" |Release Date || {{{release date|09/19/2013}}} |- style="background:#ffffff" |Author || {{{author|[[histat]]}}} |- style="background:#ffffff" |Type of game || {{{type|Source Port}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== '''NXEngine DC''' is a port of Caitlin Shaw's [http://nxengine.sourceforge.net/ NXEngine], which itself was an open source rewrite of Studio Pixel's platformer, Doukutsu Monogatari (also known as Cave Story). ==Downloads== * nxengine-dreamcast-1.0.cdi - [http://sourceforge.net/projects/nxdc/files/nxengine-dreamcast-1.0.cdi.zip Ready to burn CDI] - 09/19/2013 * nxdc-0.13.09.19 - [http://sourceforge.net/projects/nxdc/files/nxdc-0.13.09.19-plainfiles.zip Plain Files] - 09/19/2013 * dcasteroids-0.0.7 - [http://sourceforge.net/projects/nxdc/files/nxdc-0.13.09.19-sd-plainfiles.zip SD Plain Files (requires SD reader)] - 09/19/2013 * nxextract - [http://sourceforge.net/projects/nxdc/files/nxextract.zip Extraction Utility] - 05/31/2013 * Cave Story - [http://studiopixel.sakura.ne.jp/binaries/dou_1006.zip Game Files] * Cave Story - [http://studiopixel.sakura.ne.jp/binaries/dou_bgm.zip Background Music] * Cave Story English Translation - [https://agtp.romhack.net/download.php?id=cavestory By Aeon Genesis] cf5f473ea824ee7a07ea50cad1277931c0ca9ac1 File:BeroDoom-02.jpg 6 1123 2347 2023-03-02T06:51:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=BeroDoom-02}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e118ab5eb43adc53657cc5695f772bbf4cc617e3 File:Doomu.jpg 6 1122 2348 2023-03-02T06:51:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Doomu}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} bc959ed996c954f626cf1b1ae34508c11498cc9f File:BeroDoom-01.jpg 6 1124 2349 2023-03-02T06:51:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=BeroDoom-01}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} bcf574ec523be8ae33a11b532ffaa3a971dd0439 DCDoom 0 1125 2350 2023-03-02T06:51:19Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|DCDoom}}} |- border="0" cellpadding="2" cellspa..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|DCDoom}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Doomu.jpg|thumb|280px| Ultimate Doom Title Screen]]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta ''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/31/02}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://en.wikipedia.org/wiki/Doom_source_port Doom Source]<br />Using [http://sdl-dc.sourceforge.net/ SDL for DC]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|No}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} DCDoom, using the SDL for Dreamcast, was Bero's first of two DOOM engines he ported to the Dreamcast, and the third port of DOOM to the Dreamcast. It was notable for having limited MIDI support, and relatively bug-free saving. When it was abandoned in a mostly complete beta stage, the iWAD/pWAD selection menu had never been completed, meaning that it normally doesn't support more than one game WAD per disc ''(doom2.wad, doomu.wad, etc.)'' or mods. It was eventually surpassed by [[nxDoom]]. [[Image:BeroDoom-01.jpg]] [[Image:BeroDoom-02.jpg]] Bero's older DOOM page can be found here: [http://www.geocities.co.jp/Playtown/2004/dcdev/index.html DCDEV] For putting multiple Doom wads on one disc, a collection of [http://dchelp.net/tag/selfboot-inducer/ Selfboot Inducer] files can be found below. ==Downloads== * Beta - [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom.zip Plain Files] - 09/12/02 * Beta - ''SBI ** [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom-sw.sbi Shareware] - 09/12/02 ** [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom-d1.sbi Doom] - 09/12/02 ** [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom-ult.sbi Ult. Doom] - 09/12/02 ** [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom-d2.sbi Doom II] - 09/12/02 ** [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom-plu.sbi Plutonia] - 09/12/02 ** [http://dcemulation.org/1-newsdump/ports/dcdoom/dcdoom-tnt.sbi TNT] - 09/12/02 * MIDI Instrument Package - [http://www.i.h.kyoto-u.ac.jp/~shom/timidity/miniinst.zip Zipfile] ==Tutorials== *''W.I.P.'' 003920456d21e0db42414b632f44e72047254e79 DoomDC 0 1126 2351 2023-03-02T06:51:46Z Unknown user 0 Created page with "Developer: DCGrendel & crt0 Version: Beta 1 Last Updated: May 9, 2002 Description: A port of the Doom engine to the Dreamcast. The only missing feature is networked pl..." wikitext text/x-wiki Developer: DCGrendel & crt0 Version: Beta 1 Last Updated: May 9, 2002 Description: A port of the Doom engine to the Dreamcast. The only missing feature is networked play. [http://www.dcemulation.org/files/software/doomdcdj.zip Disc Juggler image (With Shareware WAD files)] [http://www.dcemulation.org/files/software/doombeta1.zip Plain files] [http://www.dcemulation.org/files/software/kdoom-bin.zip kDoom Plain Files] [ftp://ftp.idsoftware.com/idstuff/doom/doom-1.8.wad.gz Shareware WAD File] 05c38b282e41b4dfcf70f741df02441184fc561c Doom for Dreamcast 0 1127 2352 2023-03-02T06:52:21Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Doom for Dreamcast |- border="0" cellpadding="2" cellsp..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Doom for Dreamcast |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Doomu.jpg|thumb|280px| Ultimate Doom Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|<i>N/A</i>}}} |- style="background:#ffffff" |Latest Version || {{{version|v1.5 Beta}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.4.zip 1.4 Stable]<br/>/[http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom1.5b1.7z 1.5 Beta]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/23/2011}}} |- style="background:#ffffff" |Author || {{{author|[[Chilly Willy]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://aminet.net/package/game/shoot/ADoomPPC ADoomPPC] an<br />[http://aminet.net/package/game/shoot/ADoom-1.3 ADoom] port}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|Yes}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50/60Hz}}} |} Doom for Dreamcast was created by developer, FPS porter, [[Chilly Willy|Chilly Willy]] (aka JLF65). ===Features=== * Mouse, keyboard, and joypad controls. * Force-feedback (Jump Pack). * Stats on the VMU LCD. * Load/save options and games from/to VMU. * Load up to four DEH, and patch WAD files per game. (No Boom support) * NTSC, PAL, and VGA support. * MIDI/MUS music, and stereo sound effects. * Latest Doom 1 shareware (1.9). ===Network=== Network support allows you to play against up to three other players across the internet. On the Dreamcast, you need the BBA to use networking. The readme describes how to setup the network options. It can be a bit involved, so please read it carefully. ===Other Ports=== While now an older Doom source port in comparison to ''Doom for Dreamcast'', ''[[nxDoom]]'' has some pre-configuration options some may find useful, and tracker support ''(IT, MOD, XM)''. ==Downloads== Stable * v1.4 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.4.zip Plain Files] - 02/27/2011 * v1.4 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.4.sbi SBI w/Source] - 02/27/2011 * v1.2 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.2.zip Plain Files] - 07/29/2010 * v1.2 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.2.sbi SBI w/Source] - 07/29/2010 * v1.1.6 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.1.6.zip Plain Files] - 09/04/2009 * v1.1.6 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom-SW-CW-1.1.6.sbi SBI w/Source] - 09/04/2009 * v1.1.5 - [http://www.fileden.com/files/2009/2/3/2304902/DCDoom-SW-CW-1.1.5.sbi SBI w/Source] - 07/25/2009 Beta * v1.5b1 - [http://dcemulation.org/1-newsdump/ports/doom4dc/DCDoom1.5b1.7z Plain Files] w/Source - 04/23/2011 2e71b91cdc81e349bfa679b3976b2052a2889747 NxDoom 0 1128 2353 2023-03-02T06:53:15Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|NxDoom}}} |- border="0" cellpadding="2" cellspa..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|NxDoom}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Doomu.jpg|thumb|280px| Ultimate Doom Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://files.frashii.com/~sp00nz/Doom/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 2.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R2.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/31/02}}} |- style="background:#ffffff" |Author || {{{author|[[BlackAura]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://en.wikipedia.org/wiki/Doom_source_port Doom Source] ([http://en.wikipedia.org/wiki/GPL GPL])<br />[[DoomDC]]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Best for<br/>Addons}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} nxDoom is a source port of Doom written by BlackAura. To play this you need to insert your own doom .WAD files. We cannot distribute those here, but we can give links to the shareware (demo). nxDoom is based on DoomDC by crt0 and DCGrendel. NxDoom supports the registered and shareware versions of Doom, The Ultimate Doom, Doom II, and Final Doom. It supports PWADs and DeHackEd patches, but only emulates vanilla Doom's features. It has VMU saving, sound, and ''music'' when downloadable music WAD files are used. ==Features== * Support for all versions of Doom * Modlist * 90% compatable PWAD loader * 90% compatable DeHacked 3.0 loader * VMU saving * All controls mapped to the controller * Music using add-on music packs * Keyboard and Mouse support * Limited BEX strings ===Controls=== Menu: * Digital Pad → Moves the cursor around * A → Select - Same as Enter on a PC * B → Back - Same as Backspace on a PC * X → No - Same as N on a PC * Y → Yes - Same as Y on a PC * Start → Turn menu off Game: * Analog Stick → Walk and Turn * L/R Triggers → Strafe left/right * Digital Pad → Change weapon * A → Fire weapon * B → Open door/use switch * X → Open door/use switch * Y → Toggle Automap * Start → Bring up menu AutoMap: * Digital Pad → Pan the view * A → Zoom in * B → Zoom out * X → Toggle follow mode * Y → Toggle automap * Start → Bring up menu ===Other Ports=== Easily configurable without much time, previous knowledge, or hassle, ''[[Doom for Dreamcast|Doom4DC]]'' has the more user friendly setup, and BBA support. It currently does not have full dehacked support, so it is not the best single player option for wads requiring dehacked. ==Downloads== * Beta 2.2 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R2.zip Plain Files] - 10/31/02 * Beta 2.1 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R1.zip Plain Files] - 09/08/02 * Beta 2.0 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2.zip Plain Files] - 09/06/02 * Beta 1 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta1.zip Plain Files] - 08/11/2002 ==Wads== * Doom Shareware v1.9 - [http://dcemulation.org/1-newsdump/ports/iwad/doom19s.zip Zipfile] * Doom 1 XM Music - [http://dcemulation.org/1-newsdump/ports/nxDoom/chipdoom.zip Zipfile] - Rename to'' 'doom1_xm.wad'. * Doom 2 XM Music - [http://dcemulation.org/1-newsdump/ports/nxDoom/chipdm2.zip Zipfile] - Rename to'' 'doom2_xm.wad'. ==Tutorials== * [[XM_music_tutorial|How to make your own XM music wads.]] ==Links== *Forum **[http://dcemulation.org/phpBB/viewtopic.php?f=14&t=96980&hilit=nxDoom Law56kers Nxdoom Collection Released!] 0481fe70ed58cf61480843e387af837b95324a7b 2376 2353 2023-03-02T06:57:43Z Unknown user 0 /* Tutorials */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|NxDoom}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Doomu.jpg|thumb|280px| Ultimate Doom Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://files.frashii.com/~sp00nz/Doom/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 2.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R2.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/31/02}}} |- style="background:#ffffff" |Author || {{{author|[[BlackAura]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://en.wikipedia.org/wiki/Doom_source_port Doom Source] ([http://en.wikipedia.org/wiki/GPL GPL])<br />[[DoomDC]]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Best for<br/>Addons}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} nxDoom is a source port of Doom written by BlackAura. To play this you need to insert your own doom .WAD files. We cannot distribute those here, but we can give links to the shareware (demo). nxDoom is based on DoomDC by crt0 and DCGrendel. NxDoom supports the registered and shareware versions of Doom, The Ultimate Doom, Doom II, and Final Doom. It supports PWADs and DeHackEd patches, but only emulates vanilla Doom's features. It has VMU saving, sound, and ''music'' when downloadable music WAD files are used. ==Features== * Support for all versions of Doom * Modlist * 90% compatable PWAD loader * 90% compatable DeHacked 3.0 loader * VMU saving * All controls mapped to the controller * Music using add-on music packs * Keyboard and Mouse support * Limited BEX strings ===Controls=== Menu: * Digital Pad → Moves the cursor around * A → Select - Same as Enter on a PC * B → Back - Same as Backspace on a PC * X → No - Same as N on a PC * Y → Yes - Same as Y on a PC * Start → Turn menu off Game: * Analog Stick → Walk and Turn * L/R Triggers → Strafe left/right * Digital Pad → Change weapon * A → Fire weapon * B → Open door/use switch * X → Open door/use switch * Y → Toggle Automap * Start → Bring up menu AutoMap: * Digital Pad → Pan the view * A → Zoom in * B → Zoom out * X → Toggle follow mode * Y → Toggle automap * Start → Bring up menu ===Other Ports=== Easily configurable without much time, previous knowledge, or hassle, ''[[Doom for Dreamcast|Doom4DC]]'' has the more user friendly setup, and BBA support. It currently does not have full dehacked support, so it is not the best single player option for wads requiring dehacked. ==Downloads== * Beta 2.2 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R2.zip Plain Files] - 10/31/02 * Beta 2.1 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R1.zip Plain Files] - 09/08/02 * Beta 2.0 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2.zip Plain Files] - 09/06/02 * Beta 1 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta1.zip Plain Files] - 08/11/2002 ==Wads== * Doom Shareware v1.9 - [http://dcemulation.org/1-newsdump/ports/iwad/doom19s.zip Zipfile] * Doom 1 XM Music - [http://dcemulation.org/1-newsdump/ports/nxDoom/chipdoom.zip Zipfile] - Rename to'' 'doom1_xm.wad'. * Doom 2 XM Music - [http://dcemulation.org/1-newsdump/ports/nxDoom/chipdm2.zip Zipfile] - Rename to'' 'doom2_xm.wad'. ==Tutorials== ==Needed Programs== There are many different ways of doing this, so I have tried to provide the simplest way of accomplishing the task. For this tutorial, use these 3 programs on a 32bit Windows XP/Vista OS. * [http://www.doomworld.com/idgames/index.php?id=11946 WinTex 5.0] ''(You may require .dll files)'' * [ftp://drsleep@server1.thefourwinds.net/data/xwe.zip eXtendable Wad Editor 1.16] - [http://www.speedyshare.com/357424336.html Mirror] * [http://pweb.jps.net/~olivierl/utils/mpt116.zip ModPlug Tracker 1.16] - [http://download.cnet.com/MODPlug-Tracker/3000-2646_4-9029.html Mirror] ==Step One: ''Extraction of music files from WAD''.== *Start WinTex. *For the purpose of this tutorial, the main wad does not need to be selected, so choose cancel at this prompt. [[Image:WinTex_1.png|140px]] *In the "PWAD to examine or modify" window, navigate to the WAD you wish to extract the music files from. Click on the "Edit PWAD" button. [[Image:WinTex_2.png|140px]] *If you wish, click on cancel to stop WinTex from displaying it's tutorial prompts. [[Image:WinTex_3.png|140px]] *At this window, select the music from the menu, or the button. [[Image:WinTex_4.png|140px]] *Highlight all the entries that appear in the list on the left. Then through the "Edit" menu select the "Save entries to file" option. [[Image:WinTex_5.png|140px]] *In this window, navigate to the folder you wish to save the individual music files to. Leave the names at their defaults, and click "Okay" for each. [[Image:WinTex_6.png|140px]] ==Step Two: ''Conversion of music files''.== *Start ModPlug Tracker. *Under "File>Open", or the "Open" icon, select a MIDI file to begin. [[Image:MPT_1.png|140px]] *Here you can adjust several settings, including the master volume slider, or check the filter options. [[Image:MPT_2.png|140px]] *Click on the "Change" button. In the following window, without changing the "Module Type" option, reduce the channels all the way down to "4". Click "Okay". [[Image:MPT_3.png|140px]] *This window will pop up showing the unused channels already checked. Make note of it, and click "Cancel". [[Image:MPT_4.png|140px]] *Click on the "Change" button a second time. In the channels option select the amount of channels found from the previous step. Under "Module Type" select either '''IT''' ''(Okay)'', or '''XM''' ''(Best Option)''. [[Image:MPT_5.png|140px]] *Select "Okay" at this prompt. [[Image:MPT_6.png|140px]] *Click on the "Patterns" tab, select the last pattern (the number on the far right), and scroll down to where the last note can be found. In that row, or the one below it, enter "B00" as shown in the picture. This is to loop the track at the end. [[Image:MPT_7.png|140px]] *Now go to "Edit>Cleanup>Cleanup Song" and select it. Choose "Yes", and "Okay" to any following prompts. [[Image:MPT_8.png|140px]] *Go to "File>Save As", or click on the "Save" button. Leaving the name as the default, choose where to save it. [[Image:MPT_9.png|140px]] That's '''one''' music track. Repeat these conversion steps for '''each''' MIDI track in the set. ==Step Three: ''Inserting converted music into a WAD''.== *Start XWE. *For the purposes of this tutorial, the main wad doesn't need selected, so choose "Cancel". [[Image:XWE_1.png|140px]] *Select the option "File>New". [[Image:XWE_2.png|140px]] *Choose where to save the new WAD file. Music WADs created for the vanilla Doom, Doom II, TNT, and Plutonia wads will '''autoload''' if named '''"DOOM1_XM.WAD"''', '''"DOOM2_XM.WAD"''', '''"TNT_XM.WAD"''', and '''"PLUT_XM.WAD"''' respectively. All other music wads, like for '''mods''', can be named to whatever you feel appropiate. [[Image:XWE_3.png|140px]] *From the menu, select "Entry>Load". [[Image:XWE_4.png|140px]] *Navigate to where you have your IT, or XM, music files stored. Highlight all the needed tracks, and click on "Open". [[Image:XWE_5.png|140px]] *Finalize the music wad just by closing it in XWE, or exiting XWE completely. You can delete this backup that it auto-creates. [[Image:XWE_6.png|140px]] ==Step Four: ''Testing the Music WAD''. ''(Optional)''== *Test the music wad, for proper looping, effects, etc... by dropping it into a port like zDoom's main folder. With the intended main wad in the same folder, drag and drop the music wad onto the zDoom executable. [[Image:ZDoomTest.png|140px]] ==Notes== ''I may expand on this later to inlcude alternative soundfonts.'' If you have any questions regarding this tutorial, or are having trouble following it, please feel free to PM me in the forums. - Stryfe ==Links== *Forum **[http://dcemulation.org/phpBB/viewtopic.php?f=14&t=96980&hilit=nxDoom Law56kers Nxdoom Collection Released!] 37b97e58fd14d64921aa5a8620c91c1b3ca38df8 2377 2376 2023-03-02T06:57:59Z Unknown user 0 /* Tutorials */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|NxDoom}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Doomu.jpg|thumb|280px| Ultimate Doom Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://files.frashii.com/~sp00nz/Doom/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 2.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R2.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/31/02}}} |- style="background:#ffffff" |Author || {{{author|[[BlackAura]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://en.wikipedia.org/wiki/Doom_source_port Doom Source] ([http://en.wikipedia.org/wiki/GPL GPL])<br />[[DoomDC]]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Best for<br/>Addons}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} nxDoom is a source port of Doom written by BlackAura. To play this you need to insert your own doom .WAD files. We cannot distribute those here, but we can give links to the shareware (demo). nxDoom is based on DoomDC by crt0 and DCGrendel. NxDoom supports the registered and shareware versions of Doom, The Ultimate Doom, Doom II, and Final Doom. It supports PWADs and DeHackEd patches, but only emulates vanilla Doom's features. It has VMU saving, sound, and ''music'' when downloadable music WAD files are used. ==Features== * Support for all versions of Doom * Modlist * 90% compatable PWAD loader * 90% compatable DeHacked 3.0 loader * VMU saving * All controls mapped to the controller * Music using add-on music packs * Keyboard and Mouse support * Limited BEX strings ===Controls=== Menu: * Digital Pad → Moves the cursor around * A → Select - Same as Enter on a PC * B → Back - Same as Backspace on a PC * X → No - Same as N on a PC * Y → Yes - Same as Y on a PC * Start → Turn menu off Game: * Analog Stick → Walk and Turn * L/R Triggers → Strafe left/right * Digital Pad → Change weapon * A → Fire weapon * B → Open door/use switch * X → Open door/use switch * Y → Toggle Automap * Start → Bring up menu AutoMap: * Digital Pad → Pan the view * A → Zoom in * B → Zoom out * X → Toggle follow mode * Y → Toggle automap * Start → Bring up menu ===Other Ports=== Easily configurable without much time, previous knowledge, or hassle, ''[[Doom for Dreamcast|Doom4DC]]'' has the more user friendly setup, and BBA support. It currently does not have full dehacked support, so it is not the best single player option for wads requiring dehacked. ==Downloads== * Beta 2.2 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R2.zip Plain Files] - 10/31/02 * Beta 2.1 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2_R1.zip Plain Files] - 09/08/02 * Beta 2.0 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta2.zip Plain Files] - 09/06/02 * Beta 1 - [http://dcemulation.org/1-newsdump/ports/nxDoom/nxDoom_Beta1.zip Plain Files] - 08/11/2002 ==Wads== * Doom Shareware v1.9 - [http://dcemulation.org/1-newsdump/ports/iwad/doom19s.zip Zipfile] * Doom 1 XM Music - [http://dcemulation.org/1-newsdump/ports/nxDoom/chipdoom.zip Zipfile] - Rename to'' 'doom1_xm.wad'. * Doom 2 XM Music - [http://dcemulation.org/1-newsdump/ports/nxDoom/chipdm2.zip Zipfile] - Rename to'' 'doom2_xm.wad'. ==How to make your own XM music wads== ==Needed Programs== There are many different ways of doing this, so I have tried to provide the simplest way of accomplishing the task. For this tutorial, use these 3 programs on a 32bit Windows XP/Vista OS. * [http://www.doomworld.com/idgames/index.php?id=11946 WinTex 5.0] ''(You may require .dll files)'' * [ftp://drsleep@server1.thefourwinds.net/data/xwe.zip eXtendable Wad Editor 1.16] - [http://www.speedyshare.com/357424336.html Mirror] * [http://pweb.jps.net/~olivierl/utils/mpt116.zip ModPlug Tracker 1.16] - [http://download.cnet.com/MODPlug-Tracker/3000-2646_4-9029.html Mirror] ==Step One: ''Extraction of music files from WAD''.== *Start WinTex. *For the purpose of this tutorial, the main wad does not need to be selected, so choose cancel at this prompt. [[Image:WinTex_1.png|140px]] *In the "PWAD to examine or modify" window, navigate to the WAD you wish to extract the music files from. Click on the "Edit PWAD" button. [[Image:WinTex_2.png|140px]] *If you wish, click on cancel to stop WinTex from displaying it's tutorial prompts. [[Image:WinTex_3.png|140px]] *At this window, select the music from the menu, or the button. [[Image:WinTex_4.png|140px]] *Highlight all the entries that appear in the list on the left. Then through the "Edit" menu select the "Save entries to file" option. [[Image:WinTex_5.png|140px]] *In this window, navigate to the folder you wish to save the individual music files to. Leave the names at their defaults, and click "Okay" for each. [[Image:WinTex_6.png|140px]] ==Step Two: ''Conversion of music files''.== *Start ModPlug Tracker. *Under "File>Open", or the "Open" icon, select a MIDI file to begin. [[Image:MPT_1.png|140px]] *Here you can adjust several settings, including the master volume slider, or check the filter options. [[Image:MPT_2.png|140px]] *Click on the "Change" button. In the following window, without changing the "Module Type" option, reduce the channels all the way down to "4". Click "Okay". [[Image:MPT_3.png|140px]] *This window will pop up showing the unused channels already checked. Make note of it, and click "Cancel". [[Image:MPT_4.png|140px]] *Click on the "Change" button a second time. In the channels option select the amount of channels found from the previous step. Under "Module Type" select either '''IT''' ''(Okay)'', or '''XM''' ''(Best Option)''. [[Image:MPT_5.png|140px]] *Select "Okay" at this prompt. [[Image:MPT_6.png|140px]] *Click on the "Patterns" tab, select the last pattern (the number on the far right), and scroll down to where the last note can be found. In that row, or the one below it, enter "B00" as shown in the picture. This is to loop the track at the end. [[Image:MPT_7.png|140px]] *Now go to "Edit>Cleanup>Cleanup Song" and select it. Choose "Yes", and "Okay" to any following prompts. [[Image:MPT_8.png|140px]] *Go to "File>Save As", or click on the "Save" button. Leaving the name as the default, choose where to save it. [[Image:MPT_9.png|140px]] That's '''one''' music track. Repeat these conversion steps for '''each''' MIDI track in the set. ==Step Three: ''Inserting converted music into a WAD''.== *Start XWE. *For the purposes of this tutorial, the main wad doesn't need selected, so choose "Cancel". [[Image:XWE_1.png|140px]] *Select the option "File>New". [[Image:XWE_2.png|140px]] *Choose where to save the new WAD file. Music WADs created for the vanilla Doom, Doom II, TNT, and Plutonia wads will '''autoload''' if named '''"DOOM1_XM.WAD"''', '''"DOOM2_XM.WAD"''', '''"TNT_XM.WAD"''', and '''"PLUT_XM.WAD"''' respectively. All other music wads, like for '''mods''', can be named to whatever you feel appropiate. [[Image:XWE_3.png|140px]] *From the menu, select "Entry>Load". [[Image:XWE_4.png|140px]] *Navigate to where you have your IT, or XM, music files stored. Highlight all the needed tracks, and click on "Open". [[Image:XWE_5.png|140px]] *Finalize the music wad just by closing it in XWE, or exiting XWE completely. You can delete this backup that it auto-creates. [[Image:XWE_6.png|140px]] ==Step Four: ''Testing the Music WAD''. ''(Optional)''== *Test the music wad, for proper looping, effects, etc... by dropping it into a port like zDoom's main folder. With the intended main wad in the same folder, drag and drop the music wad onto the zDoom executable. [[Image:ZDoomTest.png|140px]] ==Notes== ''I may expand on this later to inlcude alternative soundfonts.'' If you have any questions regarding this tutorial, or are having trouble following it, please feel free to PM me in the forums. - Stryfe ==Links== *Forum **[http://dcemulation.org/phpBB/viewtopic.php?f=14&t=96980&hilit=nxDoom Law56kers Nxdoom Collection Released!] 6335733fb2640093b6806139d497bda11ad7689f File:MPT 1.png 6 1129 2354 2023-03-02T06:57:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1d9d739df441c40ef26f6fff46033771073e37f1 File:MPT 2.png 6 1131 2355 2023-03-02T06:57:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d2218d4a12d0d4b30a6166fc75b505fc34b005c4 File:MPT 3.png 6 1130 2356 2023-03-02T06:57:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 60cf2fed9bdd9f73d452f6ec773f4d55928e7a00 File:MPT 6.png 6 1132 2357 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 6}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ed259a3b899025c89009d24600044cdcbbc57664 File:MPT 5.png 6 1133 2358 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 5}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 190cb149506a358ace16295d7c4bd78033616345 File:MPT 4.png 6 1134 2359 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d60fabe98923a841af4dd9c8b5d8bc980c9b99c6 File:MPT 7.png 6 1137 2360 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 7}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} dafc54cde1edd93f9e1d74494585711b45cecd07 File:MPT 9.png 6 1135 2361 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 9}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 6f16ccb980876a33089d008c18d5d2129310eba1 File:MPT 8.png 6 1136 2362 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=MPT 8}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2d3ed421142bcb745217030f547c14bbc8b04d50 File:WinTex 3.png 6 1138 2363 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=WinTex 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0018ecdb06998970e4a208abe72da228ad4fafda File:WinTex 2.png 6 1139 2364 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=WinTex 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} aa168a3eb0e60ab075a88efbd21d7d685b839edc File:WinTex 1.png 6 1140 2365 2023-03-02T06:57:12Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=WinTex 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 696fb6ee68cd4fe013c407ff8be798351da97c2d File:WinTex 6.png 6 1141 2366 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=WinTex 6}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 3b7fa33c9d27b3307030702c6ceade2556e374b1 File:WinTex 4.png 6 1142 2367 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=WinTex 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ef30abbc21da3b3c3cfe6efa1ca06281b4b92c80 File:WinTex 5.png 6 1143 2368 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=WinTex 5}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0a841c92cdf8ddc0e7cad4199cc91f3d17f80445 File:XWE 1.png 6 1146 2369 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=XWE 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c4d01f3c9e33d6500ee5849f6318fb44ff34345a File:XWE 3.png 6 1145 2370 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=XWE 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b289be338924f81bd5fc666554bc5d0b147b017a File:XWE 2.png 6 1144 2371 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=XWE 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} cdb317c467fbc50e6452acd976bb440ca16fa9d6 File:XWE 6.png 6 1148 2372 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=XWE 6}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 67cd0ec4acce8c15ff92879b4fae728a1a9e941f File:XWE 5.png 6 1149 2373 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=XWE 5}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 507858c2490fa30d5cd611fed2a66f18cafd17c1 File:XWE 4.png 6 1147 2374 2023-03-02T06:57:13Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=XWE 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a3a62cb0ee1c7b5914212d75fd53b71ffb14f54b File:ZDoomTest.png 6 1150 2375 2023-03-02T06:57:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=ZDoomTest}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 48acc027ef490ffe3b3046138fa3d2b607d793b9 File:Here-02.jpg 6 1151 2378 2023-03-02T06:59:19Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Here-02}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} aa5dc43f112ca504cb8f20e0098cea20b50d57ba File:Heretictitle.jpg 6 1152 2379 2023-03-02T06:59:19Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Heretictitle}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 556b25ecc6d7dbdc3dc00a7cfe84996e77b17222 File:Here-01.jpg 6 1153 2380 2023-03-02T06:59:19Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Here-01}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e4ba5fe8cd6142a59543d58e715e06a2f2deb62c Heretic 0 1154 2381 2023-03-02T06:59:25Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heretic |- border="0" cellpadding="2" cellspacing="1" a..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heretic |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Heretictitle.jpg|Thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.geocities.co.jp/Playtown/2004/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown Beta''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dcheretic.zip Plain Files] |- style="background:#ffffff" |Release Date || {{{release date|09/09/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|''Unknown Source''}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:Here-01.jpg|240px| Heretic]] [[Image:Here-02.jpg|240px| Heretic]] ===Features=== * Support for mouse, joystick, keyboard. * Supports sound. * Support music with GUS patch. * VMU saving, with compression. ===Bugs=== * Intermittent working sound. ==Downloads== * Unknown Beta - [http://dcemulation.org/1-newsdump/games-demos/dcheretic.zip Plain Files] - 09/09/2002 * MIDI Instruments - [http://www.i.h.kyoto-u.ac.jp/~shom/timidity/miniinst.zip Zipfile] * [http://www.doomworld.com/idgames/index.php?id=7044 Heretic 1.2 Shareware] @ Doomworld * [http://www.idsoftware.com/games/vintage/heretic/ Heretic Full Registered] @ id Software ''(purchase)'' ==Links== * [http://www.ravensoft.com/ Raven Software] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) ab37e49dc05540bbeff7879af73913c1ca8a31d5 File:Hexen02.jpg 6 1155 2382 2023-03-02T07:01:53Z Unknown user 0 wikitext text/x-wiki Hexen02 e9dd3562e0454d177064f7fc30b6f629b5f88239 File:Hexen01.jpg 6 1156 2383 2023-03-02T07:02:08Z Unknown user 0 wikitext text/x-wiki Hexen01 cc4259233b923912b261b45dedad527706ae8f19 Hexen 0 1157 2384 2023-03-02T07:02:13Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hexen |- border="0" cellpadding="2" cellspacing="1" ali..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hexen |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Hexen01.jpg|Thumb|300px| Main Menu]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.geocities.co.jp/Playtown/2004/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown Beta''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dchexen.zip Plain Files] |- style="background:#ffffff" |Release Date || {{{release date|07/12/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://www.libsdl.org/projects/hexen/ Hexen SDL]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:Hexen02.jpg|240px| Title Screen]] ===Features=== * Support for mouse, joystick, keyboard. * Supports sound. * Support music with GUS patch. * VMU saving, with compression. ===Bugs=== * Intermittent working sound. ==Downloads== * Unknown Beta - [http://dcemulation.org/1-newsdump/games-demos/dchexen.zip Plain Files] - 07/12/2002 * MIDI Instrument Package - [http://www.i.h.kyoto-u.ac.jp/~shom/timidity/miniinst.zip Zipfile] * [http://www.doomworld.com/idgames/index.php?id=7045 Hexen 1.1 Shareware] @ Doomworld * [http://www.idsoftware.com/games/vintage/hexen/ Hexen Full Registered] @ id Software ''(purchase)'' ==Links== * [http://www.ravensoft.com/ Raven Software] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) 5ab4c021cfea00050a6945f970646349af4e2668 File:HexII-1.jpg 6 1159 2385 2023-03-02T07:03:25Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=HexII-1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 11a98b2f7f1fe2e0f6934853470c741a43976e11 File:HexII-2.jpg 6 1158 2386 2023-03-02T07:03:25Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=HexII-2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 11fc704d549c2265a059b021d4fda5f4f2ef727d File:HexII-3.jpg 6 1160 2387 2023-03-02T07:03:25Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=HexII-3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a3fbb9835a212bd1c2042ae26c4a41358814666e Hexen II 0 1161 2388 2023-03-02T07:03:29Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hexen II |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hexen II |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:HexII-1.jpg|Thumb|300px| Hexen II]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://sourceforge.net/projects/dcquake/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown Alpha''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://sourceforge.net/projects/dcquake/files/hexen2/2002-08-11/dchexen2-2002-08-11-bin.zip/download Plain Files] |- style="background:#ffffff" |Release Date || {{{release date|08/11/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[ftp://phoebus@server1.thefourwinds.net/raven-games/hexenworld/hexen2source.zip Hexen 2 Source]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:HexII-2.jpg|240px| Hexen II]] [[Image:HexII-3.jpg|240px| Hexen II]] ===Features=== * Working with '''''glhexen2''''' only, because ''hexen2'' soft render uses x86 asm code. * Full control using pad, except for console. * Mouse, and keyboard support. * Sound. * VMU saving, with zlib compression and icon. * CD-DA music if you read data from pc using dcload-ip, and cd-da from cd. * No networking. * No MIDI music * Only tested with demo version data files. ===Bugs=== * Transparency bug. ==Downloads== * DCHexen 2 - [http://prdownloads.sourceforge.net/dcquake/dchexen2-2002-08-11-bin.zip Plain Files] - 08/11/2002 * DCHexen 2 - [http://prdownloads.sourceforge.net/dcquake/dchexen2-2002-07-24-bin.zip Plain Files] - 07/24/2002 * DCHexen 2 - [http://prdownloads.sourceforge.net/dcquake/dchexen2-2002-07-24.tar.gz Source] - 07/24/2002 * [ftp://phoebus@server1.thefourwinds.net/raven-games/hexenworld/h2demo.exe Hexen II v1.11 Demo] @ Raven-Games * [http://www.idsoftware.com/games/vintage/hexen2/ Hexen II Full Registered] @ id Software ''(purchase)'' ==Links== * [http://www.ravensoft.com/ Raven Software] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) 1b180e31765f52c6159d151e087c77b6c147a972 File:Rott02.png 6 1163 2389 2023-03-02T07:05:05Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rott02}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 91bf5976d5beb144b5143d2724f876d282b1ee33 File:Rott01.png 6 1162 2390 2023-03-02T07:05:05Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rott01}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} aaf36bc52461d278cb35c183007004f99afa2eaf File:Rott03.png 6 1164 2391 2023-03-02T07:05:05Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rott03}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d55d5a158e2952ffc747911420b2d345de9d1dfa File:Rott05.png 6 1166 2392 2023-03-02T07:05:05Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rott05}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 69e2b20d35ff0812785a1d3a806bca7465972a90 File:Rott04.png 6 1167 2393 2023-03-02T07:05:05Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rott04}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2c97135feedae570c5fc403c6ea7cd7b37471b69 File:Rott06.png 6 1165 2394 2023-03-02T07:05:05Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rott06}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f61a7b5b1ae0dfaa68e004a6ff45b04081dcc851 RoTT DC 0 1168 2395 2023-03-02T07:05:23Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Rise of the Triad |- border="0" cellpadding="2" cellspa..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Rise of the Triad |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Rott03.png|Thumb|300px| The Hunt Begins]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://sdl-dc.sourceforge.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0-2a}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://sourceforge.net/projects/sdl-dc/files/rottdc/1.0-2a/rottdc-1.0-2a-bin.zip/download Plainfiles] |- style="background:#ffffff" |Release Date || {{{release date|03/22/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://icculus.org/rott/ RoTT for Linux]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:Rott02.png|240px| RoTT image]][[Image:Rott06.png|240px| RoTT image]] The source code to Rise of the Triad was released under the GNU General Public License on 20th of December 2002. On December 22, 2002, Rise of the Triad for Linux was released, and was subsequently ported using [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] by [[Bero]]. [[Image:Rott01.png|240px| RoTT image]][[Image:Rott04.png|240px| RoTT image]][[Image:Rott05.png|240px| RoTT image]] ===Features=== * REGISTERED/SUPERCD/SITELICENCE run from last plainfiles release. ''(untested)'' * Disk swap support. * Full button support - L/R trigger for strafe, up/down for look, etc. * Better mouse support, wheel, etc. * Fully playable with joystick . * VMU saves, with compression. * Sound, and music*, support. * No network support. ==Downloads== * rottdc-1.0-2a - [http://sourceforge.net/projects/sdl-dc/files/rottdc/1.0-2a/rottdc-1.0-2a-bin.zip/download Plainfiles] - 03/22/2003 * rottdc-1.0-2 - [http://prdownloads.sourceforge.net/sdl-dc/rottdc-1.0-2-bin.zip Plainfiles] - 03/09/2003 * rottdc-1.0 - [http://prdownloads.sourceforge.net/sdl-dc/rottdc-1.0-bin.zip Plainfiles] - 02/13/2002 * MIDI romdisk - [http://sourceforge.net/projects/sdl-dc/files/common/midi-instrument/midi-instrument.zip/download Zipfile] - 05/24/2003 (*required for music) * Shareware Game Files ** [http://www.3drealms.com/rott/ Official 3D Realms Page] * Rise of the Triad: Shareware ''/w Deluxe Edition Levels'' - [http://www.dcevolution.net/index.php?id=rise_of_the_triad via Dcevolution] (Ready to burn CDI image) ==Links== * [ftp://ftp.3drealms.com/source/rottsource.zip Rise of the Triad Source code] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) fea615545443f18540117e5059658bbf6488c653 JamBombs 0 1169 2396 2023-03-02T07:06:24Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JamBombs |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JamBombs |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|''No Screenshot Available}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20070914053927/dcgrendel.thewaffleiron.net/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|''Below}}} |- style="background:#ffffff" |Release Date || {{{release date|11/01/2001}}} |- style="background:#ffffff" |Author || {{{author|[[DcGrendel]]}}} |- style="background:#ffffff" |Type of game || {{{type|Minesweeper Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> ''"This is intended for serial cable owners, and '''might''' lock on machines without one attached."'' ==Downloads== * Unknown version - [http://dcemulation.org/1-newsdump/games-demos/jambombs/JamBombs.zip Plain Files] - 11/01/2001 * Unknown version - [http://dcemulation.org/1-newsdump/games-demos/jambombs/Jambombs.sbi SBI] - 11/01/2001 190476c0e5c14a9729d0ac02e9a5a5ff977a92fe 2397 2396 2023-03-02T07:06:30Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JamBombs |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|''No Screenshot Available}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20070914053927/dcgrendel.thewaffleiron.net/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|''Below}}} |- style="background:#ffffff" |Release Date || {{{release date|11/01/2001}}} |- style="background:#ffffff" |Author || {{{author|[[DcGrendel]]}}} |- style="background:#ffffff" |Type of game || {{{type|Minesweeper Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ''"This is intended for serial cable owners, and '''might''' lock on machines without one attached."'' ==Downloads== * Unknown version - [http://dcemulation.org/1-newsdump/games-demos/jambombs/JamBombs.zip Plain Files] - 11/01/2001 * Unknown version - [http://dcemulation.org/1-newsdump/games-demos/jambombs/Jambombs.sbi SBI] - 11/01/2001 32869fa0fe6c3e2a322ff14f040de77fefca8a68 Rocket Racer 0 1170 2398 2023-03-02T07:07:04Z Unknown user 0 Created page with "Developer: Trilinear Version: Beta 2 Description: A futuristic-styled racing game. [http://www.dcemulation.org/files/software/dihbNero.zip Nero Image] [http://www.dcem..." wikitext text/x-wiki Developer: Trilinear Version: Beta 2 Description: A futuristic-styled racing game. [http://www.dcemulation.org/files/software/dihbNero.zip Nero Image] [http://www.dcemulation.org/files/software/dihbDJ.zip Disc Juggler Image] [http://www.dcemulation.org/files/software/rocket2.zip Plain Files] 75b29d878d2d305105e58478b81c50bf4266ee86 File:Sdlwolf3d.jpg 6 1171 2399 2023-03-02T07:07:39Z Unknown user 0 wikitext text/x-wiki Sdlwolf3d 8041fc0127b78dc24fd400a693d0003b41c77e3b SdlWolf 0 1172 2400 2023-03-02T07:07:46Z Unknown user 0 Created page with "{{Infobox_Ports_Information| image=[[Image:Sdlwolf3d.jpg|250px|thumb|sdlWolf load screen]]| name=sdlWolf| version=Beta 1| downloads=[[#Downloads|Plainfiles]]<br />[..." wikitext text/x-wiki {{Infobox_Ports_Information| image=[[Image:Sdlwolf3d.jpg|250px|thumb|sdlWolf load screen]]| name=sdlWolf| version=Beta 1| downloads=[[#Downloads|Plainfiles]]<br />[http://dchelp.net/selfboot-inducer-file-repository/?type=Games SBI files] (DCHelp)| release date=06/04/2006| author=[[OneThirty8]]| original=[http://www.bebits.com/app/2718 Wolfenstein3D SDL]| best=No| refreshrate=60Hz| isactive=No }} ==History== Based on Steven Fuller's Wolfenstein 3D SDL for Linux, sdlWolf was the first Dreamcast port of Wolfenstein 3D and Spear of Destiny to support sound and music. It has since been overshadowed by fackue's port of [[Wolf4SDL\DC]], which is compatible with more versions of the data files and will play the game directly from the original CD-ROM. In contrast, sdlWolf requires that you burn a copy your Wolf3D or Spear of Destiny data files to the same CD as the Dreamcast program file. This port itself is still very good. It play's well with the occassional bugs, has save support, and has menu selection capability for the Spear of Destiny expansions - ''Mission 2: Return to Danger'', and ''Mission 3: Ultimate Challenge''. ==Downloads== ===Plainfiles=== * SDL Wolfenstein (Full) - [http://dcemulation.org/1-newsdump/ports/sdlWolf/sdlWolf-full.zip Plainfiles] * SDL Spear of Destiny (Full) - [http://dcemulation.org/1-newsdump/ports/sdlWolf/SpearsdlSpear-full.zip Plainfiles] * SDL Wolfenstein (Demo) - [http://dcemulation.org/1-newsdump/ports/sdlWolf/sdlWolf-SW.zip Plainfiles] * SDL Spear of Destiny (Demo) - [http://dcemulation.org/1-newsdump/ports/sdlWolf/sdlSpear-demo.zip Plainfiles] ===Source=== * sdlWolf Source Code - [http://dcemulation.org/1-newsdump/ports/sdlWolf/wolf-release.tgz Gzip Tarball] ===Demos=== * Wolfenstein 3D (Shareware) 1.4 - [ftp://ftp.3drealms.com/share/1wolf14.zip Zipfile] * Spear of Destiny (Shareware) - [ftp://gamers.org/pub/games/uwp-uml/demos/soddemo2.zip Zipfile] bb07c398f0add65376d645468915a164c92abf90 File:Wolf4SDL-dc-1.jpg 6 1173 2401 2023-03-02T07:08:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Wolf4SDL-dc-1}} |date=1899-11-30 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} eac4ec8acb3bd987076df629cd9b06449f3e35aa File:Wolf4SDL-dc-2.jpg 6 1174 2402 2023-03-02T07:08:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Wolf4SDL-dc-2}} |date=1899-11-30 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d42d992ed334341bfb3d9ea5d84e85c771999e51 File:Wolf3d-Act-TitleScreen.jpg 6 1175 2403 2023-03-02T07:08:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Wolf3d-Act-TitleScreen}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 76f80bf677db81ac3c264cc6cc6894c4c7a5b1be Wolf4SDL\DC 0 1176 2404 2023-03-02T07:08:51Z Unknown user 0 Created page with "{{Infobox_Ports_Information| name=Wolf4SDL\DC| image=[[Image:Wolf3d-Act-TitleScreen.jpg|thumb|250px| Title Screen]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| ve..." wikitext text/x-wiki {{Infobox_Ports_Information| name=Wolf4SDL\DC| image=[[Image:Wolf3d-Act-TitleScreen.jpg|thumb|250px| Title Screen]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=1.6| downloads=[http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Full-14-Activision.7z Plain Files] (Wolf3D, Full, Activision)<br />[http://dchelp.dcemulation.org/downloads/Sod4SDL-DC_16_Full.7z Plain Files] (SoD, Full)| release date=10/04/2008| author=[[fackue]]| original=[http://www.chaos-software.de.vu/ Wolf4SDL]| best=Yes| refreshrate=60Hz| isactive=''Unknown }} ==History== Wolf4SDL\DC is a port of Wolf4SDL by [[fackue]] whose goal is to say as true as possible to vanilla Wolfenstein 3D and Spear of Destiny. Wolf4SDL is constantly updated by it's author, Ripper, so expect an equally updated DC port.<br /><br /> [[Image:Wolf4SDL-dc-1.jpg|250px| Wolf4SDL on the DC!]][[Image:Wolf4SDL-dc-2.jpg|250px|Blazkowicz on VMU!]] ===Known Bugs=== * None<br /><br /> ===Controls=== * Dpad → movement * Analog left → previous weapon * Analog right → next weapon * A → shoot * B → strafe * X → open * Y → run * C → previous weapon * Z → next weapon<br /><br /> ==Downloads== * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Full-11.7z Plain Files] ''(Wolf, Full, 1.1) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Full-14-Apogee.7z Plain Files] ''(Wolf, Full, 1.4 Apogee) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Full-14-Activision.7z Plain Files] ''(Wolf, Full, 1.4, GT\ID\Activ.) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Shareware-10.7z Plain Files] ''(Wolf, Shareware, 1.0) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Shareware-11.7z Plain Files] ''(Wolf, Shareware, 1.1) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Shareware-12.7z Plain Files] ''(Wolf, Shareware, 1.2) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_Shareware-14.7z Plain Files] ''(Wolf, Shareware, 1.4) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Sod4SDL-DC_16_Full.7z Plain Files] ''(SoD, Full) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Sod4SDL-DC_16_Demo.7z Plain Files] ''(SoD, Demo) - 10/04/2008'' * 1.6 - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_16_source.7z Source Files] - ''10/04/2008'' * Previous Version ** BETA - [http://dchelp.dcemulation.org/downloads/Wolf4SDL-DC_Beta_Full-14-Activision.zip Plain Files] ''(Wolf, Full) - 3/04/08'' ==Links== * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=101062 Wolfenstein 3D Collection] ''(Non-retail mod collection)'' [[Category:Homebrew game]] ba83ed7f962d1a46c03b5d09dfbd315f7a546e67 Wolf3D DC 0 1177 2405 2023-03-02T07:09:48Z Unknown user 0 Created page with "Developer: crt0 Version: 1 Description: A Wolfenstein 3D port to the Dreamcast. Controls: (using controller) Up/Down/Left/Right on D-Pad moves, B is escape, A is enter..." wikitext text/x-wiki Developer: crt0 Version: 1 Description: A Wolfenstein 3D port to the Dreamcast. Controls: (using controller) Up/Down/Left/Right on D-Pad moves, B is escape, A is enter, Left trigger is space, Right trigger is control. (using keyboard) Everything is mapped to what it was in the original game, except the S3 key of the DC keyboard is the only key mapped to stab/shoot/fire etc. You must provide the game data files in order to use the below binaries. [http://www.dcemulation.org/files/software/wolf3d_demo.zip Wolf3D Demo Version binary] [http://www.dcemulation.org/files/software/wolf3d_full.zip Wolf3D Full Version binary] [http://www.dcemulation.org/files/software/sod_demo.zip Spear of Destiny Demo Version binary] [http://www.dcemulation.org/files/software/sod_full.zip Spear of Destiny Full Version binary] 462f44d30b51b4a8df972bbb1143260e041a9888 File:AmandaDC.jpg 6 1178 2406 2023-03-02T07:11:19Z Unknown user 0 wikitext text/x-wiki AmandaDC 8221a4e640efbb7f24aecd3453e569cb231e7c26 Amanda The Witch's Apprentice 0 1179 2407 2023-03-02T07:11:36Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Amanda The Witch's Apprentice |- border="0" cellpadding..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Amanda The Witch's Apprentice |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:AmandaDC.jpg|thumb|280px| Amanda the Witch]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20060501003309/consolevision.com/members/trilinear/index.html Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/AmandaDC.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/08/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Amanda is an apprentice to a powerful witch named Gertrude. One day Gertrude left to gather some rare bat's wings and put Amanda in charge of the cottage. After a while Amanda noticed that Zero, the witch's black cat, had slipped out an open door. Amanda realized how angry her master would be if she lost her favorite cat, Amanda quickly grabbed her master's backup broom and followed the cat's tracks to a large cave... Gameplay based on the "infamous worm game" at '[http://web.archive.org/web/20080501211246/http://www.liquidcode.org/worm.html http://www.liquidcode.org/worm.html]'. ===Controls=== * Start - to restart level * Start+Y - quit * Stick - rotate view * RTrigger - zoom in * A - go up * X - take screenshot(if using BBA or cable) ==Downloads== * Beta 1 - [http://dcemulation.org/1-newsdump/games-demos/AmandaDC.zip Plain Files] - 06/08/2002 * Amanda (Windows/GL) Beta 1 - [http://web.archive.org/web/20060501003309/http://consolevision.com/members/trilinear/AmandaWin.zip Win32 Exe] * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] dad5cefaa1cbcbee2add610f4bca7d60466d2015 File:Another ast.jpg 6 1180 2408 2023-03-02T07:12:07Z Unknown user 0 wikitext text/x-wiki Another ast 0dcdcf5c2344cf8a1ecf540dbbe33dd25a559e6b Another Asteroids Clone 0 1181 2409 2023-03-02T07:12:09Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Another Asteroids Clone |- border="0" cellpadding="2" c..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Another Asteroids Clone |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Another_ast.jpg|center|thumb|250px| Another Asteroid Clone]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|''Unknown}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/an_ast_clone/aster_10_BIN.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/05/2004}}} |- style="background:#ffffff" |Author || {{{author|Eytan Kaziberdov}}} |- style="background:#ffffff" |Type of game || {{{type|Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== This is an Asteriods clone from Kamjin. 1. Shoot the rocks!<br/> 2. See number 1 ===Controls=== * Analog Stick, or D-Pad controls Left and Right * Right Trigger is Thrust * Left Trigger to active super weapons * Fire is A button. * Shield is B Button * HyperSpace is X button * Start to skip Intro Screen, and restart on Game Over. * Start to pause game play. ==Downloads== * 1.0 - [http://dcemulation.org/1-newsdump/games-demos/an_ast_clone/aster_10_BIN.zip Plain Files] - 04/05/2004 * 1.0 - [http://dcemulation.org/1-newsdump/games-demos/an_ast_clone/aster_10_DJ_SB.zip DiscJuggler] - 04/05/2004 d562ff83640bb5ed9b6dd11ebba836892e9505f2 2410 2409 2023-03-02T07:12:29Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Another Asteroids Clone |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Another_ast.jpg|center|thumb|250px| Another Asteroid Clone]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|''Unknown}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/an_ast_clone/aster_10_BIN.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/05/2004}}} |- style="background:#ffffff" |Author || {{{author|Eytan Kaziberdov}}} |- style="background:#ffffff" |Type of game || {{{type|Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} This is an Asteriods clone from Kamjin. 1. Shoot the rocks!<br/> 2. See number 1 ===Controls=== * Analog Stick, or D-Pad controls Left and Right * Right Trigger is Thrust * Left Trigger to active super weapons * Fire is A button. * Shield is B Button * HyperSpace is X button * Start to skip Intro Screen, and restart on Game Over. * Start to pause game play. ==Downloads== * 1.0 - [http://dcemulation.org/1-newsdump/games-demos/an_ast_clone/aster_10_BIN.zip Plain Files] - 04/05/2004 * 1.0 - [http://dcemulation.org/1-newsdump/games-demos/an_ast_clone/aster_10_DJ_SB.zip DiscJuggler] - 04/05/2004 952a542f0a8164cbe95a5e8e1fc552e50ec75c24 Freeware homebrew games 0 76 2411 2187 2023-03-02T07:12:50Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[SonicRoboBlast2|Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 63e1fd1e3322e45d09985a45558e66a79481210f Armored Campaign 0 1182 2412 2023-03-02T07:12:55Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Armored Campaign |- border="0" cellpadding="2" cellspac..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Armored Campaign |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Armcamp_2.jpg|thumb|center|280px| Armored Campaign]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20021021091614/consolevision.com/trilinear/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/arm_camp/campaign.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/21/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|Multiplayer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> Multiplayer tank deathmatch for dreamcast. [[Image:Armcamp_1.jpg|250px| Armored Campaign]] ===Controls=== * Start - to begin game and quit game * Stick - turn / tilt cannon * RTrigger - accelerate * A - fire * Y - reset cannon to forward ===Bugs=== * yes ==Downloads== * Beta 1.2 - [http://dcemulation.org/1-newsdump/games-demos/arm_camp/campaign.zip Plain Files] - 05/21/2002 * Beta 1.2 - [http://dcemulation.org/1-newsdump/games-demos/arm_camp/ArmoredCampaign.sbi SBI] - 05/21/2002 * [http://www.dcevolution.net/index.php?id=sapplay SAPPlay] @ DCEvolution bdbf411bf2e1dd54b68d5dc06bba5903ea366dd3 File:Armcamp 1.jpg 6 1183 2413 2023-03-02T07:13:20Z Unknown user 0 wikitext text/x-wiki Armcamp 1 903f4789a31d767513198b93223f6d2a21125d94 File:Armcamp 2.jpg 6 1184 2414 2023-03-02T07:13:26Z Unknown user 0 wikitext text/x-wiki Armcamp 2 b6f497929cedc2cc1b063cf382f4b7bea28a5939 File:Lady1.png 6 1185 2415 2023-03-02T07:15:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lady1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0d87d72e572df406244ad771a826152baa885c6c File:Lady2.png 6 1187 2416 2023-03-02T07:15:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lady2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7480b910daa2421a24228e42d4cfc591d7242056 File:Ladykill.png 6 1186 2417 2023-03-02T07:15:11Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Ladykill}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e492741a470e37b7ecc3ed47fc62312f9b159df9 Lady Killer 0 1188 2418 2023-03-02T07:15:20Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Lady Killer |- border="0" cellpadding="2" cellspacing="..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Lady Killer |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Ladykill.png|275px|thumb| Gameplay screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.dreamcast.es/downloads.php?descarga=255 Homepage (Español)]<br />[http://translate.google.com/translate?hl=en&sl=es&u=http://www.dreamcast.es/downloads.php%3Fdescarga%3D255&ei=pE95S-n1KNGVtgfcqMy_Cg&sa=X&oi=translate&ct=result&resnum=1&ved=0CAgQ7gEwAA&prev=/search%3Fq%3Dhttp://www.dreamcast.es/downloads.php%253Fdescarga%253D255%26hl%3Den%26rls%3Dcom.microsoft:en-us English Translated (Google)]}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dreamcast.es/downloads.php?descarga=255 Homepage (Account needed)]<br />[http://dcemulation.org/1-newsdump/games-demos/ladykill-dc.rar Local Mirror]}}} |- style="background:#ffffff" |Release Date || {{{release date|01/24/2010}}} |- style="background:#ffffff" |Author || {{{author|[[Chui]]}}} |- style="background:#ffffff" |Type of game || {{{type|Adult Arcade Remake}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Ladykiller is a remake made from scratch by the people from the GP2x homebrew scene, and it is very faithful to the arcade game of the same name. '''''Attention! This game is for adults (+18). Play it at your own discretion. ''''' The goal is simple: Uncover the boxes, avoid the enemies, while making sure you don't drown. [[Image:Lady2.png]][[Image:Lady1.png]] Chui is responsible for the Dreamcast port of the game. Insert credits with the R button, play with the A, and B to exit. The download includes the binary files all ready to create a disc image with Bootdreams. ===Arcade=== Lady Killer's protagonist is Gonta, a funny little diver the player controls. After choosing one of the first 6 girls (8 in total), you'll have to guide Gonta with the joystick over an invisible tile-grid set over water. His only skill is diving (he can't shoot or jump), and everytime he does so a tile turns, progressively revealing more of the girls' figure. 303b18c6f9fabb94da6982907ad75d6d1b687ed0 MiniGolf 0 1189 2419 2023-03-02T07:18:30Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | MiniGolf |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | MiniGolf |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:MiniGolf1.jpg|center|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://dreamcast.dcemu.co.uk/minigolf.php Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/minigolf.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Licantropo}}} |- style="background:#ffffff" |Type of game || {{{type|Mini Golf}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Mini Golf game for the Dreamcast. Ported to the Dreamcast by Wraggster, the original GP2X version can be found [http://www.wiki.gp2x.org/wiki/Minigolf here]. [[Image:MiniGolf2.jpg|center|thumb|320px| Play Screen]] In-Game text is in Spanish. ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/minigolf.zip Plain Files] - ''Unknown release date'' 411569f2008ec695a9087f0b7b043c8e0485b353 File:MiniGolf1.jpg 6 1190 2420 2023-03-02T07:18:55Z Unknown user 0 wikitext text/x-wiki MiniGolf1 82ab54fe0e9ed61bb047c97163bda17c5dcd8196 File:MiniGolf2.jpg 6 1191 2421 2023-03-02T07:19:01Z Unknown user 0 wikitext text/x-wiki MiniGolf2 b21ef9a913bf58376fc19f95288ff1ecef978861 File:Pocketvolley.png 6 1192 2422 2023-03-02T07:20:16Z Unknown user 0 wikitext text/x-wiki Pocketvolley 97f060b7c5884f7941e635ee328eb2cb4a14add9 Pocket Volleyball DC 0 1193 2423 2023-03-02T07:20:18Z Unknown user 0 Created page with "{{Infobox_Ports_Information| name=Pocket Volleyball DC| image=[[Image:pocketvolley.png|center|250px]]| homepage=[http://www.maturion.de/2008/11/pocket-volleyball-dc/ Homepa..." wikitext text/x-wiki {{Infobox_Ports_Information| name=Pocket Volleyball DC| image=[[Image:pocketvolley.png|center|250px]]| homepage=[http://www.maturion.de/2008/11/pocket-volleyball-dc/ Homepage]| version=0.5| downloads=[http://www.maturion.de/dreamcast/volleyballdc.rar Plain Files]<br/> [http://www.maturion.de/dreamcast/volleyballsrc.rar Source code]| release date=11/09/2008| author=[[Maturion]]| original=[http://www.losersjuegos.com.ar/juegos/volleyball/volleyball.php Pocket Volleyball]| best=Yes| refreshrate=60Hz| isactive=Yes }} Pocket Volleyball DC is a port of Pocket Volleyball, a small Volleyball gamefor two players. You can use a keyboard or a gamepad to play. [[Category:Homebrew game]] 5b5783cd3ab865e44bc60a36cfe25e72cef036d0 2424 2423 2023-03-02T07:20:24Z Unknown user 0 wikitext text/x-wiki {{Infobox_Ports_Information| name=Pocket Volleyball DC| image=[[File:pocketvolley.png|center|250px]]| homepage=[http://www.maturion.de/2008/11/pocket-volleyball-dc/ Homepage]| version=0.5| downloads=[http://www.maturion.de/dreamcast/volleyballdc.rar Plain Files]<br/> [http://www.maturion.de/dreamcast/volleyballsrc.rar Source code]| release date=11/09/2008| author=[[Maturion]]| original=[http://www.losersjuegos.com.ar/juegos/volleyball/volleyball.php Pocket Volleyball]| best=Yes| refreshrate=60Hz| isactive=Yes }} Pocket Volleyball DC is a port of Pocket Volleyball, a small Volleyball gamefor two players. You can use a keyboard or a gamepad to play. [[Category:Homebrew game]] bb88e95b2d0d5ac7b35b5fdf48b92949cff1d751 DreamZZT 0 1194 2425 2023-03-02T07:21:27Z Unknown user 0 Created page with "Developer: Sam Steele Version that we have here: 2.0 Description: A recreation of the ZZT engine for the Dreamcast. [http://www.dcemulation.org/files/software/dreamzzt-..." wikitext text/x-wiki Developer: Sam Steele Version that we have here: 2.0 Description: A recreation of the ZZT engine for the Dreamcast. [http://www.dcemulation.org/files/software/dreamzzt-2.0-rc1n.zip Nero Image] [http://www.dcemulation.org/files/software/dreamzzt-2.0-rc1p.zip Plain files] [http://www.dcemulation.org/files/software/dreamzzt-1.0.tar.gz Plain Files (v 1.0)] [http://www.dcemulation.org/files/software/dreamzzt-romdisk.bin Romdisk (v 1.0?)] [http://www.dcemulation.org/files/software/dp10dj.zip Source Code (v 1.0)] [http://www.dcemulation.org/files/software/dreamzzt-tag-demo.tar.gz Tag Demo (recovered from original 2.0 release?)] 90d7d9e78674defddcac7f2a67cc0f839f7c5564 Barrage 0 1195 2426 2023-03-02T07:21:55Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Barrage |- border="0" cellpadding="2" cellspacing="1" a..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Barrage |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Barrage_1.jpg|thumb|center|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050313143932/www.storm-studios.net/sdl/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/barrage/barrage.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Will Sams]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://lgames.sourceforge.net/index.php?project=Barrage Barrage]}}} |- style="background:#ffffff" |Type of game || {{{type|Mouse Shooter}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Barrage is a rather violent action game with the objective to kill and destroy as many targets as possible within 3 minutes. The player controls a gun that may either fire small or large grenades at soldiers, jeeps and tanks. It is a very simple gameplay though it is not that easy to get high scores. A Dreamcast mouse & keyboard are required to be able to play the game. ===Controls=== * Left Button → Fire a large grenade. * Middle Button / Ctrl + Left Button → Fire a small grenade. * Right Button → Reload gun to full 36 rounds. ==Downloads== * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/barrage/barrage.zip Plain Files] - 06/07/2003 * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/barrage/barrage_src.zip Source] - 06/07/2003 6d67c5ac6be432a380c445df3ed1a190eeb11707 2428 2426 2023-03-02T07:22:24Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Barrage |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Barrage_1.jpg|thumb|center|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050313143932/www.storm-studios.net/sdl/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/barrage/barrage.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Will Sams]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://lgames.sourceforge.net/index.php?project=Barrage Barrage]}}} |- style="background:#ffffff" |Type of game || {{{type|Mouse Shooter}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Barrage is a rather violent action game with the objective to kill and destroy as many targets as possible within 3 minutes. The player controls a gun that may either fire small or large grenades at soldiers, jeeps and tanks. It is a very simple gameplay though it is not that easy to get high scores. A Dreamcast mouse & keyboard are required to be able to play the game. ===Controls=== * Left Button → Fire a large grenade. * Middle Button / Ctrl + Left Button → Fire a small grenade. * Right Button → Reload gun to full 36 rounds. ==Downloads== * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/barrage/barrage.zip Plain Files] - 06/07/2003 * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/barrage/barrage_src.zip Source] - 06/07/2003 13e5947c8df0e336bbabbcb0848658540d54dcca 2429 2428 2023-03-02T07:22:29Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Barrage |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Barrage_1.jpg|thumb|center|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050313143932/www.storm-studios.net/sdl/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/barrage/barrage.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Will Sams]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://lgames.sourceforge.net/index.php?project=Barrage Barrage]}}} |- style="background:#ffffff" |Type of game || {{{type|Mouse Shooter}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Barrage is a rather violent action game with the objective to kill and destroy as many targets as possible within 3 minutes. The player controls a gun that may either fire small or large grenades at soldiers, jeeps and tanks. It is a very simple gameplay though it is not that easy to get high scores. A Dreamcast mouse & keyboard are required to be able to play the game. ===Controls=== * Left Button → Fire a large grenade. * Middle Button / Ctrl + Left Button → Fire a small grenade. * Right Button → Reload gun to full 36 rounds. ==Downloads== * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/barrage/barrage.zip Plain Files] - 06/07/2003 * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/barrage/barrage_src.zip Source] - 06/07/2003 abfe010624ae33cc06aa8b3a704da1e9b780b31d File:Barrage 1.jpg 6 1196 2427 2023-03-02T07:22:13Z Unknown user 0 wikitext text/x-wiki Barrage 1 7eb29705a7ba9332ef0bba00e1b11bbf6c1faacf Blockdrop 0 1197 2430 2023-03-02T07:23:03Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Blockdrop |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Blockdrop |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Blockdrop1.jpg|center|thumb|300px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|0.1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/blockdrop/blockdrop-0.1.scrambled.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[nymus]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== '''''Via ReadMe:<br /> '' "BlockDrop is a tetris-like game by me, nymus ''It is my first game on DC and my very first complete programming project of any kind. ''Due to this fact, it may have a few bugs, but the current build (which I will call 0.1) is very much playable. ''There might be a small bug when you try to rotate a block that's close to the edge of the screen, but I think it adds to the challenge." '' ==Controls== *DPAD_LEFT: move block left *DPAD_RIGHT: move block right *DPAD_DOWN: move block down (if you want to speed things up) *BUTTON_A: rotate block ==Downloads== * 0.1 - [http://dcemulation.org/1-newsdump/games-demos/blockdrop/blockdrop-0.1.scrambled.zip Plain Files] - ''Unknown release date * 0.1 - [http://dcemulation.org/1-newsdump/games-demos/blockdrop/Blockdrop.sbi SBI] - ''Unknown release date ===Author's Note=== '' "The backgrounds are from my favorite Dreamcast game: Soul Calibur <br />(All that material is (c) Namco and should be used with discretion, may not be sold for profit etc, etc,. If it is wrong to use them, please let me know)" '' 0db4e39546bcf985881801b6c47ebf27a52774d0 2432 2430 2023-03-02T07:23:31Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Blockdrop |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Blockdrop1.jpg|center|thumb|300px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|0.1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/blockdrop/blockdrop-0.1.scrambled.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[nymus]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== '''''Via ReadMe:<br /> '' "BlockDrop is a tetris-like game by me, nymus ''It is my first game on DC and my very first complete programming project of any kind. ''Due to this fact, it may have a few bugs, but the current build (which I will call 0.1) is very much playable. ''There might be a small bug when you try to rotate a block that's close to the edge of the screen, but I think it adds to the challenge." '' ==Controls== *DPAD_LEFT: move block left *DPAD_RIGHT: move block right *DPAD_DOWN: move block down (if you want to speed things up) *BUTTON_A: rotate block ==Downloads== * 0.1 - [http://dcemulation.org/1-newsdump/games-demos/blockdrop/blockdrop-0.1.scrambled.zip Plain Files] - ''Unknown release date * 0.1 - [http://dcemulation.org/1-newsdump/games-demos/blockdrop/Blockdrop.sbi SBI] - ''Unknown release date ===Author's Note=== '' "The backgrounds are from my favorite Dreamcast game: Soul Calibur <br />(All that material is (c) Namco and should be used with discretion, may not be sold for profit etc, etc,. If it is wrong to use them, please let me know)" '' 4fa98ef5c62c2df2098d94fed4d340e00823b4b3 File:Blockdrop1.jpg 6 1198 2431 2023-03-02T07:23:20Z Unknown user 0 wikitext text/x-wiki Blockdrop1 841aec25e8628cb5c1dda639658d13697918bd46 File:Texttext.jpg 6 1199 2433 2023-03-02T07:24:01Z Unknown user 0 wikitext text/x-wiki Texttext 80e6e2699a4fd3d4a81c1140223983d4a7827038 DC Text Text Revolution 0 1200 2434 2023-03-02T07:24:04Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | DC Text Text Revolution |- border="0" cellpadding="2" c..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | DC Text Text Revolution |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Texttext.jpg|thumb|center|280px| Text Text]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/DCTTR.rar Source w/<br/>Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Type of game || {{{type|Dance Dance<br/>Revolution Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Dreamcast SDL port of Text Text Revolution. The plain files binary can be found in the''' 'cd' '''directory. ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/DCTTR.rar Source w/Plain Files] - ''Unknown release date'' 3dacf44eb673fbd0425d9632d45ccaa3d577595d DCShooter 0 1201 2435 2023-03-02T07:24:35Z Unknown user 0 Created page with "Developer: [http://jimbomania.com/ Jimbo] Version: 0.0.5x Last Updated: March 22, 2002 Description: A first person shooter for the Dreamcast. [http://www.dcemulation...." wikitext text/x-wiki Developer: [http://jimbomania.com/ Jimbo] Version: 0.0.5x Last Updated: March 22, 2002 Description: A first person shooter for the Dreamcast. [http://www.dcemulation.org/files/software/dihbNero.zip Nero Image] [http://www.dcemulation.org/files/software/dihbDJ.zip Disc Juggler Image] [http://www.dcemulation.org/files/software/dcshooter005x.exe Plain files] 45da9da5f04c2ebcb9f16765b019d4f27d0f2a16 DCBlast 0 1202 2436 2023-03-02T07:25:07Z Unknown user 0 Created page with "Developer: EvilSporkMan Version: 0.46 Last Updated: Tuesday, May 21, 2002 Description: A shoot 'em up. Submitted as an entry for the 2002 programming contest. [http:/..." wikitext text/x-wiki Developer: EvilSporkMan Version: 0.46 Last Updated: Tuesday, May 21, 2002 Description: A shoot 'em up. Submitted as an entry for the 2002 programming contest. [http://www.dcemulation.com/dl/dl.php3?url=files/software/DCBlast046Nero.zip Nero image] [http://www.dcemulation.com/dl/dl.php3?url=files/software/DCBlast046DJ.zip DJ image] [http://www.dcemulation.com/dl/dl.php3?url=files/software/DCBlastbin0046.zip Plain files] bb11f24eca167a1062964d02ca68ead6a3a42ae4 RedSpotGames 0 1203 2437 2023-03-02T07:29:23Z Unknown user 0 Created page with "German publishing company founded by Max Scharl of DCS." wikitext text/x-wiki German publishing company founded by Max Scharl of DCS. 54998f58b43b5e34f65f928efba9029498866a18 File:Convey1.jpg 6 1204 2438 2023-03-02T07:30:00Z Unknown user 0 wikitext text/x-wiki Convey1 0a01933b7091ebb77991a6e86f58e0521e1dfc6c Convey 0 1205 2439 2023-03-02T07:30:03Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Convey |- border="0" cellpadding="2" cellspacing="1" al..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Convey |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Convey1.jpg|center|thumb| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlbin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[Ian Micheal]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Convey is a game written originally in BASIC for use on RISC OS computers, here it is converted to SDL for multiplatform enjoyment. Guide the blob along the conveyer belt collecting the red blobs, if you miss any you go round again. http://www.cloudsprinter.com/software/conveysdl/ ===Needed=== * Requires Dreamcast keyboard to play. ==Downloads== * [http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlbin.zip Plain Files] * [http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlsrc.zip Source] 7eb9007dabf55371a0e6a56b48a1d083172a262a 2440 2439 2023-03-02T07:30:12Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Convey |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Convey1.jpg|center|thumb| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlbin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[Ian Micheal]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Convey is a game written originally in BASIC for use on RISC OS computers, here it is converted to SDL for multiplatform enjoyment. Guide the blob along the conveyer belt collecting the red blobs, if you miss any you go round again. http://www.cloudsprinter.com/software/conveysdl/ ===Needed=== * Requires Dreamcast keyboard to play. ==Downloads== * [http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlbin.zip Plain Files] * [http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlsrc.zip Source] ea7df9d4818bd7684075956e73100d7403591518 File:Bugs1.jpg 6 1206 2441 2023-03-02T07:31:07Z Unknown user 0 wikitext text/x-wiki Bugs1 b21e9844c545f48a7ec5d2c856bb57a223296156 File:Bugs2.jpg 6 1207 2442 2023-03-02T07:31:16Z Unknown user 0 wikitext text/x-wiki Bugs2 ce5da2bf34144e164582ee1efe3516d9eda78f34 Bugs 0 1208 2443 2023-03-02T07:31:18Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Bugs |- border="0" cellpadding="2" cellspacing="1" alig..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Bugs |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Bugs1.jpg|center|thumb|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/bug.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|2005}}} |- style="background:#ffffff" |Author || {{{author|[[Kamjin]]}}} |- style="background:#ffffff" |Type of game || {{{type|Space Invaders Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> Kill the Bugs! <br/> [[Image:Bugs2.jpg|center|thumb|320px| Play Screen]] Dpad/Analog moves left/right and A fires.<br/> Press Y to exit back to BootMenu or DCLOAD during gameplay.<br/> MotherShip will reset the Shields.<br/> ''(Which you'll really need to do often on later levels) ===Known Bugs=== * One of the aliens decides to march in the wrong direction every few levels. * Player's ship is always on Turbo Fire (Since the Bonus code is rem'd out) * Sounds Don't always play like they should when bugs move to kamekaze mode. * Kamekaze bugs don't ever hit the player. ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/bug.zip Plain Files] - ??/??/2005 16b8700495bd9e488953b649b753e258a62b3847 2444 2443 2023-03-02T07:31:28Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Bugs |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Bugs1.jpg|center|thumb|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/bug.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|2005}}} |- style="background:#ffffff" |Author || {{{author|[[Kamjin]]}}} |- style="background:#ffffff" |Type of game || {{{type|Space Invaders Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Kill the Bugs! [[Image:Bugs2.jpg|center|thumb|320px| Play Screen]] Dpad/Analog moves left/right and A fires.<br/> Press Y to exit back to BootMenu or DCLOAD during gameplay.<br/> MotherShip will reset the Shields.<br/> ''(Which you'll really need to do often on later levels) ===Known Bugs=== * One of the aliens decides to march in the wrong direction every few levels. * Player's ship is always on Turbo Fire (Since the Bonus code is rem'd out) * Sounds Don't always play like they should when bugs move to kamekaze mode. * Kamekaze bugs don't ever hit the player. ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/bug.zip Plain Files] - ??/??/2005 dd62bbb2107fd8632b4821d6c7cc90567de392fa Christian Berger 0 1209 2445 2023-03-02T07:32:10Z Unknown user 0 Created page with "Christian Berger was a German Dreamcast developer. He contributed to the [[LinuxDC]] project, most notably a driver for the SEGA LAN adapter (HIT-0300) and for the SEGA VMU LC..." wikitext text/x-wiki Christian Berger was a German Dreamcast developer. He contributed to the [[LinuxDC]] project, most notably a driver for the SEGA LAN adapter (HIT-0300) and for the SEGA VMU LCD Display. *[http://www-public.tu-bs.de:8080/~berger/ Christian Berger's website] 1ac64c648e3da9d3d18483b996d20062a59b226d File:Clonetris1b.jpg 6 1210 2446 2023-03-02T07:33:30Z Unknown user 0 wikitext text/x-wiki Clonetris1b c0610d055269c5d836cc536ba0ca85a7475caa24 File:Clonetris2b.jpg 6 1211 2447 2023-03-02T07:33:37Z Unknown user 0 wikitext text/x-wiki Clonetris2b c4755b0871c4c7b84d28a244ea0dbaf6457accaf Clonetris 0 1212 2448 2023-03-02T07:33:43Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | CloneTris |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | CloneTris |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Clonetris1b.jpg|thumb|center|250px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050409141434/games.timeforplanb.net/index.php Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dcemulation.org/1-newsdump/games-demos/clonetris/clonetris.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|02/20/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Toastman]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone<br/>''(Duh...)}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== '''''Via Toastman's Archived Site: '' 'Clonetris is a Tetris-like game for the Sega Dreamcast system. It was created as a stop-gap project while I learned some of the workings of the Dreamcast and began to grow larger than I wanted it to. ''All work on Clonetris has ceased. I don't even have a working copy of the source anymore. ''This game has been rated 'A' - Suitable for All by the [http://web.archive.org/web/20060301144555/http://dreamon.cyberdogcastle.com/dirb/ DIRB: Dreamcast Independant Rating Board] (archived link).' [[Image:Clonetris2b.jpg|Left|250px| Menu Screen]] ===Features=== * In order to have background music in this release. Put a MP3 in the '' 'music' '' folder at the cd root, and rename it to ''nevski3.mp3''. ===Bugs=== * The included MP3 may have problems, but if you want to use it, try encoding it differently. ''(You can pre-test in an emulator) ==Downloads== * Unknown Version - [http://www.dcemulation.org/1-newsdump/games-demos/clonetris/clonetris.zip Plain Files] - 02/20/2002 * Unknown Version - [http://www.dcemulation.org/1-newsdump/games-demos/clonetris/Clonetris.sbi.zip SBI] - 02/20/2002 * Unknown Version - [http://www.dcemulation.org/1-newsdump/games-demos/clonetris/Clone_Tetris.zip Nero] - 02/20/2002 ce02a0fb9cef0bfb6dc97d41878131c048e8893e Clonetris 0 1212 2449 2448 2023-03-02T07:33:59Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | CloneTris |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Clonetris1b.jpg|thumb|center|250px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050409141434/games.timeforplanb.net/index.php Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dcemulation.org/1-newsdump/games-demos/clonetris/clonetris.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|02/20/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Toastman]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone<br/>''(Duh...)}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== '''''Via Toastman's Archived Site: '' 'Clonetris is a Tetris-like game for the Sega Dreamcast system. It was created as a stop-gap project while I learned some of the workings of the Dreamcast and began to grow larger than I wanted it to. ''All work on Clonetris has ceased. I don't even have a working copy of the source anymore. ''This game has been rated 'A' - Suitable for All by the [http://web.archive.org/web/20060301144555/http://dreamon.cyberdogcastle.com/dirb/ DIRB: Dreamcast Independant Rating Board] (archived link).' [[File:Clonetris2b.jpg|Left|250px| Menu Screen]] ===Features=== * In order to have background music in this release. Put a MP3 in the '' 'music' '' folder at the cd root, and rename it to ''nevski3.mp3''. ===Bugs=== * The included MP3 may have problems, but if you want to use it, try encoding it differently. ''(You can pre-test in an emulator) ==Downloads== * Unknown Version - [http://www.dcemulation.org/1-newsdump/games-demos/clonetris/clonetris.zip Plain Files] - 02/20/2002 * Unknown Version - [http://www.dcemulation.org/1-newsdump/games-demos/clonetris/Clonetris.sbi.zip SBI] - 02/20/2002 * Unknown Version - [http://www.dcemulation.org/1-newsdump/games-demos/clonetris/Clone_Tetris.zip Nero] - 02/20/2002 5d98d7c111c2a723c47dfd43c32b67418a47fc5d File:DcQuad 1.jpg 6 1213 2450 2023-03-02T07:35:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=DcQuad 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0657b672b4095a064689b5df5ce264329dcc8630 File:DcQuad 2.jpg 6 1214 2451 2023-03-02T07:35:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=DcQuad 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 9f897cf83156819885e0caca51f0611302eea6f7 File:DcQuad 3.jpg 6 1215 2452 2023-03-02T07:35:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=DcQuad 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} bbfca5b6c2302145f437e565b2b09fe8dcf7e3c9 File:DcQuad 4.jpg 6 1216 2453 2023-03-02T07:35:28Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=DcQuad 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 49c9a56cd72f039aca37a9166cc5eb907888b13b DcQuad 0 1217 2454 2023-03-02T07:35:50Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | dcQuad |- border="0" cellpadding="2" cellspacing="1" al..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | dcQuad |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:DcQuad_1.jpg|thumb|center|280px| dcQuad]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|''None}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta R5}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dcquad/dcQuad.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|03/15/2002}}} |- style="background:#ffffff" |Author || {{{author|Douglas Winslow}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone}}} |- style="background:#ffffff" |Active || {{{isactive|''No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== <br/> [[Image:DcQuad_4.jpg|250px| dcQuad]] [[Image:DcQuad_2.jpg|250px| dcQuad]] [[Image:DcQuad_3.jpg|250px| dcQuad]] '''''Quote via author:<br/> '' 'dcQuad is a damn near perfect clone of the A-Mode game play in the popular 1989 Nintendo Gameboy version of Tetris. Developed (and tirelessly play-tested) on my own free time over the course of the past year, it's a must-have title for anybody who's into the whole "falling blocks" genre.' ==Downloads== * Beta R5 - [http://dcemulation.org/1-newsdump/games-demos/dcquad/dcQuad.zip Plain Files] - 03/15/2002 * Beta R5 - [http://dcemulation.org/1-newsdump/games-demos/dcquad/dcQuad.sbi SBI] - 03/15/2002 75619cc5be0a9ff385d475775930bb995216b295 Giana's Return 0 1218 2455 2023-03-02T07:40:04Z Unknown user 0 Created page with "[[Image:Grboss2.jpg]] *Giana's Return - [http://www.gianas-return.de/ Official Site]" wikitext text/x-wiki [[Image:Grboss2.jpg]] *Giana's Return - [http://www.gianas-return.de/ Official Site] bb5c4a4a2f9b2ea1b84590cb7e42b26e7dd4e25c 2457 2455 2023-03-02T07:40:50Z Unknown user 0 wikitext text/x-wiki [[File:Grboss2.jpg]] *Giana's Return - [http://www.gianas-return.de/ Official Site] 8eb28ee43c4ced07315bcfbd36d3583d8f22593b File:Grboss2.jpg 6 1219 2456 2023-03-02T07:40:25Z Unknown user 0 wikitext text/x-wiki Grboss2 371c543384d53742cb53e5028a80e2729da57aab File:Gnr.jpg 6 1220 2458 2023-03-02T07:42:19Z Unknown user 0 wikitext text/x-wiki Gnr 77d5b28e9d69c2d245612ca4fd66ad0d8358fe35 The Adventures of Gus and Rob 0 1221 2459 2023-03-02T07:42:21Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Adventures of Gus and Rob |- border="0" cellpadding..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Adventures of Gus and Rob |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Gnr.jpg|thumb|center|280px|The Adventures of Gus and Rob]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://archives.dcemulation.org/consolevision/members/metafox/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|GC Edition}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://archives.dcemulation.org/consolevision/members/metafox/gnr.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/23/03}}} |- style="background:#ffffff" |Author || {{{author|[[MetaFox]]}}} |- style="background:#ffffff" |Type of game || {{{type|Single-player}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Adventures of Gus and Rob is an adventure game that was announced on August 23, 2003, the day the demo created for the Games Convention in Germany was released to the public. Since nothing was revealed about the game after the release of the Game Convention demo, the game is considered to be on indefinite hold. ==Downloads== * G|C Edition - [http://archives.dcemulation.org/consolevision/members/metafox/gnr.zip Plain Files Plain Files] - 05/21/2002 f5d8035d8707664d549e52ee0b7fa4cdad615ace 2460 2459 2023-03-02T07:42:27Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Adventures of Gus and Rob |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Gnr.jpg|thumb|center|280px|The Adventures of Gus and Rob]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://archives.dcemulation.org/consolevision/members/metafox/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|GC Edition}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://archives.dcemulation.org/consolevision/members/metafox/gnr.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/23/03}}} |- style="background:#ffffff" |Author || {{{author|[[MetaFox]]}}} |- style="background:#ffffff" |Type of game || {{{type|Single-player}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Adventures of Gus and Rob is an adventure game that was announced on August 23, 2003, the day the demo created for the Games Convention in Germany was released to the public. Since nothing was revealed about the game after the release of the Game Convention demo, the game is considered to be on indefinite hold. ==Downloads== * G|C Edition - [http://archives.dcemulation.org/consolevision/members/metafox/gnr.zip Plain Files Plain Files] - 05/21/2002 e368f1839963ba81afaaca4a0cdf34c852f0c5ed File:Dodgin diamond 2 1.jpg 6 1222 2461 2023-03-02T07:43:57Z Unknown user 0 wikitext text/x-wiki Dodgin diamond 2 1 df69a805ed045f2c39dfc135c537e44739f95530 File:Dodgin diamond 2 2.jpg 6 1223 2462 2023-03-02T07:44:04Z Unknown user 0 wikitext text/x-wiki Dodgin diamond 2 2 b42f3b91009724bfd9168f45a85e2ec42d0f492c Dodgin' Diamond 2 0 1224 2463 2023-03-02T07:44:06Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Dodgin' Diamond 2 |- border="0" cellpadding="2" cellspa..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Dodgin' Diamond 2 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:dodgin diamond 2_1.jpg|thumb|250px| Game Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.screamcast.net/html/game_dodgindiamond2.htm Quzar] ''(now defunct)''<br/>/[http://ltk.dciberia.net/dreamcast/dreamcast.htm LTK] ''(now defunct)''}}} |- style="background:#ffffff" |Latest Version || {{{version|0.2.1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_quzar.zip Plain Files]<br/>/[http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_src_quzar.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|January 25th, 2006}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]<br/>/[[LTK]]}}} |- style="background:#ffffff" |Type of game || {{{type|Shmup}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== There were two separate, unrelated, ports of this game to the Dreamcast. One was ported by LTK, itself based off of the GP2X port by 'A600'. The Quzar version is generally considered to be superior, and was based off of the PC version. ===Quzar version=== A space shooter created by Juan J Martinez, ported to Dreamcast by Quzar. JJM's own description of the game: "This is a little shot'em up [sic] arcade game for one or two players. It aims to be an 'old school' arcade game with low resolution graphics, top-down scroll action, energy based gameplay and different weapons with several levels of power." [[Image:dodgin diamond 2_2.jpg|300px| Game Screen]] ====Progress/Version==== The newest Dreamcast port includes multiplayer and high score support! This updated port was an entry into the 2005 Dream On contest (Tier 4). As of this writing, Juan's latest update of the game is '0.2.1' ==Links== * [http://www.usebox.net/jjm/dd2/ Official Dodgin' Diamond 2 page] ==Downloads== * ''Quzar (0.2.1)'' - [http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_quzar.zip Plain Files] - ''01/25/2006'' * ''Quzar (0.2.1)'' - [http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_src_quzar.zip Source] - ''01/25/2006'' * ''LTK (unknown)'' - [http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_ltk.zip Plain Files] - ''09/20/2005'' 5c2f902dffb5226ec8a24ff90141c801fba47799 2464 2463 2023-03-02T07:44:29Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Dodgin' Diamond 2 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:dodgin diamond 2_1.jpg|thumb|250px| Game Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.screamcast.net/html/game_dodgindiamond2.htm Quzar] ''(now defunct)''<br/>/[http://ltk.dciberia.net/dreamcast/dreamcast.htm LTK] ''(now defunct)''}}} |- style="background:#ffffff" |Latest Version || {{{version|0.2.1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_quzar.zip Plain Files]<br/>/[http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_src_quzar.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|January 25th, 2006}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]<br/>/[[LTK]]}}} |- style="background:#ffffff" |Type of game || {{{type|Shmup}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== There were two separate, unrelated, ports of this game to the Dreamcast. One was ported by LTK, itself based off of the GP2X port by 'A600'. The Quzar version is generally considered to be superior, and was based off of the PC version. ===Quzar version=== A space shooter created by Juan J Martinez, ported to Dreamcast by Quzar. JJM's own description of the game: "This is a little shot'em up [sic] arcade game for one or two players. It aims to be an 'old school' arcade game with low resolution graphics, top-down scroll action, energy based gameplay and different weapons with several levels of power." [[File:dodgin diamond 2_2.jpg|300px| Game Screen]] ====Progress/Version==== The newest Dreamcast port includes multiplayer and high score support! This updated port was an entry into the 2005 Dream On contest (Tier 4). As of this writing, Juan's latest update of the game is '0.2.1' ==Links== * [http://www.usebox.net/jjm/dd2/ Official Dodgin' Diamond 2 page] ==Downloads== * ''Quzar (0.2.1)'' - [http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_quzar.zip Plain Files] - ''01/25/2006'' * ''Quzar (0.2.1)'' - [http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_src_quzar.zip Source] - ''01/25/2006'' * ''LTK (unknown)'' - [http://dcemulation.org/1-newsdump/games-demos/dodgin_diamond_2/dd2_ltk.zip Plain Files] - ''09/20/2005'' e404f4bbc29afeac3ccc6567a80df97da956d470 CyRUS64 0 1225 2465 2023-03-02T07:48:05Z Unknown user 0 Created page with "CyRUS64 was a Dreamcast developer. He was one of the leaders of B00B! Dreamcast Research and he did the majority of news posts there from late 2000 until late 2003. He relea..." wikitext text/x-wiki CyRUS64 was a Dreamcast developer. He was one of the leaders of B00B! Dreamcast Research and he did the majority of news posts there from late 2000 until late 2003. He released a GameBoy emulator in 2000, [[Boob!boy]], and he was an active member in the Xbox scene. He was also working on a Dreamcast emulator for the PC, [[Icarus]], which got never released and contributed a lot to [[StrmnNrmn]]'s N64 emulator [[DaedalusDC|Daedalus]]. He somehow disapeared in late 2003. *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=6880 CyRUS64's Profile on DCEmulation.org] *[http://www.boob.co.uk B00B! Dreamcast Research] dcb9f3569649c593fb9cf8667b5a40b7f7d9f0cb NxMakaqu 0 1226 2466 2023-03-02T07:48:41Z Unknown user 0 Created page with "''nxMakaqu'' is a source port of id Software's Quake engine to the Sega Dreamcast by [[Manoel|Manoel Kasimier aka 'Fragger']]. It is a merger of [[BlackAura]]'s ''nxQuake''..." wikitext text/x-wiki ''nxMakaqu'' is a source port of id Software's Quake engine to the Sega Dreamcast by [[Manoel|Manoel Kasimier aka 'Fragger']]. It is a merger of [[BlackAura]]'s ''nxQuake'' and the PC ''Quake'' engine ''Makaqu'', and thus is the official continuation of ''[[nxQuake]]''. nxMakaqu supports the registered and shareware versions of Quake. It also has a modlist that allows you to select the original game, mods, and total conversions. ==History== In late 2002, the nxQuake base was used in a project named ''RADQuake''. Black Aura would send his changes into the project, so work on nxQuake was halted in favour of ''RADQuake''. ''RADQuake'' was maintained by Black Aura, speud, and Manoel Kasimier. It implemented VMU saving support, preliminary sound support, and preliminary rumble pack support. In late 2005, work on nxQuake moved to a project named ''nxMakaqu''. It is a combination of Black Aura's ''nxQuake'' and Manoel Kasimier's PC ''Quake'' source port, Makaqu. ''nxMakaqu'' has improved sound support, CD music support, an improved modlist, multiple renderer changes, and support for skyboxes. ''nxMakaqu'' has superseded both [[nxQuake]] and [[RADQuake]], and is the current active incarnation of the ''nxQuake'' codebase. ==Downloads== *Makaqu 1.3 - [http://quakedev.dcemulation.org/fragger/dl.php3?url=Makaqu1.3.zip Plain Files] *Makaqu 1.2 - [http://quakedev.dcemulation.org/fragger/dl.php3?url=Makaqu1.2.zip Plain Files] ==nxMakaqu v1.3 Changes== '''Dreamcast-related bugfixes''':<br />''Quoted straight from the included readme.txt'' * ''Updated the default deadzone values for the controller.'' * ''Fixed the cd_enabled cvar being not registered if there is no audio tracks on the disc.'' '''Common changes''': * ''Updated BlackAura's e-mail address in the credits screen.'' ==nxMakaqu v1.2 Changes== '''Dreamcast-related bugfixes''': * ''Corrected the name of mouse button 1.'' * ''Fixed the "Pause" option in the Audio Options menu.'' * ''nxMakaqu would crash when trying to save FrikFiles, because it tried to save them in the CD. Now the FrikFiles are saved in the RAM. There's no way to same them on the VMU yet though.'' * ''The "screenshot" command is ignored now. This was done to prevent crashes, because it tried to save them in the CD.'' '''Windows-related bugfixes''': * ''Fixed the crosshair being not displayed correctly in some video cards.'' * ''Fixed the network menus (they were disabled by mistake).'' '''Common bugfixes''': * ''Fixed a small problem with the interpolation (sorry, can't remember what it was).'' * ''Now the translucent viewmodels are drawn over the translucent water instead of under it.'' * ''Fixed the network protocol (demos recorded with some mods were not working).'' * ''Fixed the "cmdline" cvar.'' * ''Fixed some menu options that were not saved in the config file.'' '''Dreamcast-related changes''': * ''Added an IP.BIN file.'' * ''Modlist support for the /ID1 directory.'' * ''Added support for the file /quake/gamedir/nxmakaqu.ini. This file can be used to set the title and description of the game in the modlist, as well as the sound samplerate, the video resolution, the size of the heap memory, and extra command line parameters.'' * ''Added 320x480 and 640x240 resolutions (640x240 is faster).'' * ''Resolutions up to 768x576 are selectable in the modlist.'' * ''Changed the default audio samplerate to 11025 Hz, thus fixing some games that needs more RAM.'' * ''The default setting for the stereo sound is set accordingly to the DC BIOS setting.'' * ''Added support for volume control of the CD audio.'' * ''The CD audio can be changed between stereo/mono, and the stereo can be reversed.'' * ''The engine can detect the amount of CD tracks and display it on the Audio Options menu.'' * ''Added support for mouse button 3 and mouse wheel. The mouse is fully supported now.'' * ''Significant changes to the analog input support. Now the analog stick's axes can be bound to any command, and the "Axis/Trigger Function" options are gone.'' * ''Added auto-repeat for the keys and face buttons while in the console or menu.'' * ''Added vibration (Puru Puru/Jump Pack) support.'' * ''Added a SVC_VIBRATE (61) message to the network protocol. Usage: SVC_VIBRATE, + 5 writebytes (special, effect1, effect2, duration, controller).'' * ''VMU saves are compressed now, and saves from version 1.0 can still be loaded.'' * ''Replaced the VMU file icon. The new one features colored borders for each game.'' * ''Added a simple VMU LCD icon.'' * ''FrikFiles are opened from the RAM if found in there, otherwise they are opened from the CD. Saving is always done in the RAM.'' '''Windows-related changes''': * ''Removed the CD audio volume control from the audio menu.'' * ''Now the engine knows the difference between CDs with no audio tracks and empty drives.'' * ''The underwater screen buffer is always used, thus making the transparencies run faster on some computers.'' '''Common changes''': * ''Improved the models of the super shotgun, nailgun, super nailgun, rocket launcher and thunderbolt. These new versions works better with interpolation and transparencies.'' * ''Added a new progs.dat file with many bugfixes and some new features.'' * ''The new progs.dat features a workaround for the solid skies in the original Quake levels. It can be disabled by typing "savedgamecfg 1" in the console.'' * ''The status bar isn't displayed when changing levels anymore.'' * The underwater warping effect runs at the same resolution of the video now.'' * ''The camera tilting during weapon recoil is smoother. Now it uses 16-bit angles instead of 8.'' * ''The Thunderbolt's lightning follows the player's rotation and movement smoothly now.'' * ''Created QC support for self.frame_interval, to customize the time of the interpolation for each entity. Setting it to -1 disables interpolation, and setting it to zero uses the default value (0.1 seconds).'' * ''Non-audio tracks are skipped when selecting an audio track in the Audio Options menu.'' * ''Added a 3D stereo mode, using the r_stereo_separation cvar. It has a few bugs.'' * ''Added options for fog and 3D stereo separation in the Developer menu. To disable the fog you must turn the developer mode off.'' * ''Added the Timescale extension.'' * ''Added a sv_compatibility cvar, to allow both network gaming and demo recording compatible with normal Quake.'' * ''Added a sv_makaqu cvar to enable Makaqu-exclusive effects (EF_SHADOW, etc.).'' '''How to burn''': * ''Add your .pak files from original Quake to the id1 dir. There's no need to rename or patch anything.'' * ''Burn as usual.'' ==Fightoon== In 2007, nxMakaqu will be used as the engine for [[Fightoon]], a cel-shaded one on one fighting game, published by [http://www.goatstore.com/ GOAT Store] Publishing. The game will be the first cell-shaded fighting game to be available on Dreamcast. ==Links== *[http://quakedev.dcemulation.org/fragger/ Fragger's Place] *[http://dcemulation.org/phpBB/viewforum.php?f=15 QuakeDev Forums] *[http://dcemulation.org/phpBB/viewtopic.php?t=73662 Topic at QuakeDev] 4308326fc82de4ed70b1e26d77d5e6d5a5451bc3 File:Bathunt.jpg 6 1227 2467 2023-03-02T08:01:26Z Unknown user 0 wikitext text/x-wiki Bathunt d9799543ba9b93d4913bb474a847bb7b67db104a File:Graforlock.jpg 6 1228 2468 2023-03-02T08:01:33Z Unknown user 0 wikitext text/x-wiki Graforlock 344adae68e51fda550511e4c18550c97fbc6acf9 Graf Orlock's Bathunt 0 1229 2469 2023-03-02T08:01:37Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Graf Orlock's Bathunt |- border="0" cellpadding="2" cel..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Graf Orlock's Bathunt |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Graforlock.jpg|thumb|center|280px| Graf Orlock's]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/bathunt/bathunt.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[OneThirty8]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} '' 'OH NO!!! Count Orlock's vampire bats got out! Can you help him round them up? Take a stroll through the woods, and if you see a bat, catch it with the "A" button. Catch all 10 bats to win. Be careful, because if you're not ready these vampire bats will suck your precious vampire blood! Lose all your blood, and you lose the game!' '' [[Image:Bathunt.jpg|280px|Bathunting]] ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/bathunt/bathunt.zip Plain Files] - ''Unknown release date'' * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/bathunt/bathunt.sbi SBI] - ''Unknown release date'' * DCEvolution: [http://www.dcevolution.net/index.php?id=dchakker DCHakker] Collection a35798cef9fbdd151e0f91d23dbc8954ffb2166f File:Dc-rtronic 1.jpg 6 1230 2470 2023-03-02T08:02:47Z Unknown user 0 wikitext text/x-wiki Dc-rtronic 1 b8338fefdd8547e043b9065dff4dddac9c5a4b32 File:Dc-rtronic 2.jpg 6 1231 2471 2023-03-02T08:02:54Z Unknown user 0 wikitext text/x-wiki Dc-rtronic 2 0c556f7155b4b250b57971cfcffb279b1368cff5 DC R-Tronic 0 1232 2472 2023-03-02T08:04:30Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin left:1em; background:#CADCFB;" !colspan="3" | DC-RTronic |- border="0" cellpadding="2" cellspacing="1..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin left:1em; background:#CADCFB;" !colspan="3" | DC-RTronic |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Dc-rtronic_1.jpg|thumb|center|250px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://unrational.blogspot.com/ Blog]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dcrt_200505.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|May 20th, 2005}}} |- style="background:#ffffff" |Author || {{{author|[[Warmtoe]]}}} |- style="background:#ffffff" |Type of game || {{{type|Robotron Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br /> [[Image:Dc-rtronic_2.jpg|center|300px| Game Screen]] '''''Brief desciption via author:'''''<br /> ''DCRTronic which was the robotron clone - using the gfx from R-Tronic by Trevor Smila Storey. <br /><br />I've not done much on it, but it has had a lot of code update. ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/dcrt_200505.zip Plain Files] - ''05/20/05'' 83af4756192e09e9d6610850d74e29abe4067d9c File:Crackattack.jpg 6 1233 2473 2023-03-02T08:05:24Z Unknown user 0 wikitext text/x-wiki Crackattack f951332a0823e657bdab5558f26bf3b2d1832493 Crack Attack 0 1234 2474 2023-03-02T08:05:30Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Crack Attack |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Crack Attack |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Crackattack.jpg|thumb|280px| Crack Attack!]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://people.msoe.edu/~russor/dc/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.1.18}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://people.msoe.edu/~russor/dc/crack-dc-exe.tar.gz Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[Toast]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Attack Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Crack-Attack is a clone of the SNES game Tetris Attack. It is available under the [http://www.gnu.org/licenses/gpl.html GPL]. Daniel Nelson wrote it for Win32 and Linux. Richard 'toast' Russo has ported it to KOS/dreamcast as part of an independent study in hardware and software for the Dreamcast. There are some outstanding issues, but its playable. ===Bugs=== * I can't get the textures to work, so I disabled them all, this is done via #ifdefs, so its reasonably easy to compile it with support for textures and see how ugly it becomes. * Sometimes, while playing, the display goes blank; I don't know why that happens, but hitting B twice should fix that. * When garbage is becoming blocks, there is a vertical line that shouldn't be there; this is ugly, but not a big problem. * After the game ends, some ugly stuff comes up, and the game stops being responsive; I think this is due to the gl reinitialization by hitting the B button. * Theres no network support; there was gonna be, but my plans to make a network adapter didn't work out so well. * Also, in ASCII gfx mode, there needs to be some sort of redraw limiting, so it doesn't look as ugly. ===Controls=== * D-pad: move the swapper * A button: swap the blocks in the swapper * B button: switch between ASCII and GL graphic modes * Y button: speed up the advancing blocks * Start button: pause, get past prompts ==Downloads== * Crack Attack 1.1.18 - [http://people.msoe.edu/~russor/dc/crack-dc-exe.tar.gz Plainfiles] - ''Unknown release date * Crack Attack 1.1.18 - [http://people.msoe.edu/~russor/dc/crack-dc-data.tar.gz Datafiles] - ''Unknown release date * Crack Attack 1.1.18 - [http://people.msoe.edu/~russor/dc/crack.cdi DiscJuggler] - ''Unknown release date ==Links== * [http://aluminumangel.org/ Crack Attack Homepage] fee1120b2406efeaa4ac5aab5d5e7593ca38e13a 2475 2474 2023-03-02T08:05:43Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Crack Attack |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Crackattack.jpg|thumb|280px| Crack Attack!]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://people.msoe.edu/~russor/dc/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.1.18}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://people.msoe.edu/~russor/dc/crack-dc-exe.tar.gz Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[Toast]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Attack Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Crack-Attack is a clone of the SNES game Tetris Attack. It is available under the [http://www.gnu.org/licenses/gpl.html GPL]. Daniel Nelson wrote it for Win32 and Linux. Richard 'toast' Russo has ported it to KOS/dreamcast as part of an independent study in hardware and software for the Dreamcast. There are some outstanding issues, but its playable. ===Bugs=== * I can't get the textures to work, so I disabled them all, this is done via #ifdefs, so its reasonably easy to compile it with support for textures and see how ugly it becomes. * Sometimes, while playing, the display goes blank; I don't know why that happens, but hitting B twice should fix that. * When garbage is becoming blocks, there is a vertical line that shouldn't be there; this is ugly, but not a big problem. * After the game ends, some ugly stuff comes up, and the game stops being responsive; I think this is due to the gl reinitialization by hitting the B button. * Theres no network support; there was gonna be, but my plans to make a network adapter didn't work out so well. * Also, in ASCII gfx mode, there needs to be some sort of redraw limiting, so it doesn't look as ugly. ===Controls=== * D-pad: move the swapper * A button: swap the blocks in the swapper * B button: switch between ASCII and GL graphic modes * Y button: speed up the advancing blocks * Start button: pause, get past prompts ==Downloads== * Crack Attack 1.1.18 - [http://people.msoe.edu/~russor/dc/crack-dc-exe.tar.gz Plainfiles] - ''Unknown release date * Crack Attack 1.1.18 - [http://people.msoe.edu/~russor/dc/crack-dc-data.tar.gz Datafiles] - ''Unknown release date * Crack Attack 1.1.18 - [http://people.msoe.edu/~russor/dc/crack.cdi DiscJuggler] - ''Unknown release date ==Links== * [http://aluminumangel.org/ Crack Attack Homepage] 18ed5c83c25fd24cb224f9a35fcd94249022ff4b File:Xu4 2.jpg 6 1237 2476 2023-03-02T08:07:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Xu4 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2c8a84c8f5c2866343ee523d70aaee0d4bb32068 File:Xu4 1.jpg 6 1235 2477 2023-03-02T08:07:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Xu4 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 254c53e363a61cffb4d431a3e596a50eb044e0d5 File:Xu4 3.gif 6 1236 2478 2023-03-02T08:07:17Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Xu4 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 4f9fddca6f6ee186a07a1a326ebcf3bfd4051888 File:Xu4 4.gif 6 1238 2479 2023-03-02T08:07:18Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Xu4 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 435200e507a999b18c9c85b54b3c95ccf95dde68 XU4 0 1239 2480 2023-03-02T08:07:23Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Ultima IV: Quest of the Avatar |- border="0" cellpaddin..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Ultima IV: Quest of the Avatar |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Xu4_1.jpg|thumb|center|280px| Title]][[Image:Xu4_2.jpg|thumb|center|280px| Gameplay]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/ultima_iv/UltimaIV.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/04/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Reaper2k2]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://xu4.sourceforge.net/index.php xu4]}}} |- style="background:#ffffff" |Type of game || {{{type|Role Playing}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> XU4 isn't a new game based on the Ultima IV story -- it is a faithful recreation of the old game, right up to the crappy graphics. If you are looking for a game with modern gameplay and graphics, this is not it -- yet. New features that improve the gameplay and keep with the spirit of the original game will be added. [[Image:Xu4_3.gif|Ultima IV]] [[Image:Xu4_4.gif|Ultima IV]] ===Features=== * Requires Dreamcast keyboard * VMU saving * VMU graphic artwork * VGA graphics pack * Stereo soundtrack ===Controls=== * A - Attack * B - Board ship / Mount horse * C - Cast (Followed by the number of the character who will do the casting, and then the letter of the spell) * D - Descend * E - Enter * F - Fire a ship's cannons (followed by the direction, broadsides only) * G - Get Chest * H - Hole up and camp (may only be used successfully with limited frequency) * I - Ignite a torch (requires torches from guilds) * J) Jimmy lock (Followed by the direction of the door) * K - Klimb (Up by default, use D to descend) * L - Locate position (Requires sextant from that pirate place) * M - Mix Reagents (Followed by the letter of a reagent, one letter per part, with no seperators. Return mixes them. If I wanted to prepare a Jinx spell with one part of black pearl, one of nightshade, and one of mandrake root, I'd type BNM and then press return. * N - New order (followed by the numbers of the characters that you want to switch) * O - Open door (followed by the direction) * P - Peer at gem (requires a gem) * Q - Quit and Save * R - Ready a weapon * S - Search (looks on the ground for unusual items) * T - Talk (You're going to want to say "name", "job", "health", and "join" to most everyone that you meet, then ask about the things that they mention, particularly the nouns.) * U - Use (Uses an item found with the search command) * V - Volume (Toggles sound) * W - Wear armor * X - Xit (Exit your horse, ship, etc and continue on foot) * Y - Yell (Yells "giddyup" or "whoa" to speed/slow your horse) * Z - Ztats (Displays status) ==Downloads== * [http://dcemulation.org/1-newsdump/games-demos/ultima_iv/UltimaIV.zip Plain Files] - 08/04/2003 * [http://dcemulation.org/1-newsdump/games-demos/ultima_iv/UltimaIV.sbi SBI] - 08/04/2003 f5a849807ecab68ab2acfca5071f83dd72acd5ad Old tools 0 195 2481 2178 2023-03-02T08:08:25Z Unknown user 0 /* Various Tools */ wikitext text/x-wiki __NOTOC__ This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) = Burning Applications = *[http://www.ahead.de/en/index.html#download Nero Burning Rom] - Burns .nrg images. If your burner supports Nero then you should use it. *[http://www.alcohol-software.com/download.php Alcohol 120%] - Burns .cdi images as well as many other formats. *[http://www.padus.com/downloads/demo.php Discjuggler] - Burns .cdi images. Nicknamed Discmangeler because so many people have problems with it. = Selfboot Kits = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dcfactory-0.9.5-FULL.exe DC Factory 0.9.5] - This is one of the best tools you can find for your DC, an all in one burning type program that utilizes scripts and auto updates, you can get the latest headlines from dcemu and everything. A must have for Dreamcast burners everywhere. *[http://www.dchomebrew.org/files/Sbinducr.exe Self Boot Inducer v2.1] - This program will uncompress and build a disc image from .sbi files. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/Selfboot.exe Selfboot] - A selfboot program by burnerO. It's a merger of Selfboot Buddy & Dir2boot. Small in size & easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dssbsfinal.zip DSSBS Final] - Disco Stu's Self Boot Solution. This is a popular DOS-based self-booting utility. It's small and easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_ultimate_selfboot_kitv4final.exe Ultimate Boot Kit V4.0 Final] - This program is very, very easy to use and supports bin2boot (data/data) method and the CDRecord (audio/data) method. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/selfboot.zip The Selfboot Kit Beta 3] - A selfboot kit by Roofus, it will currently create selfbooting CD's for DreamSNES, NesterDC, DCDivx & FreeSCI. *[http://www.dcemulation.org/files/needed/N&DG%204%20dummies%20vr2.exe Nester & DCGNUboy 4 Dummies] - A program put together by Jack_15, this is what he had to say about it: "Well here is the kit I made it is for NesterDC and DcGunuyboy it can uncompress roms that are on .zip and .rar file extensions. you don't have to put any thing in different directories the kit makes them for you!"- Version 2 Uploaded Now *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_quakedc_selfboot_kitv1.zip QuakeDC Selfboot Kit V1] - A program used to selfboot [[Quake|QuakeDC]]. It's another proggy from Pinoy2201 *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dreamboot1-2.zip Dreamboot 1-2] - A selfbooting program called DreamBoot, It has been tried out & it's good & easy to use, so if you've had problems getting programs like DCFactory, DSSBS Final etc. working on your system you might want to give this one a try. = Boot Discs = *[http://www.dchomebrew.org/Demomnu.shtml Demo Menu] - Loads emulators from [[Multisession_CD|multisession CDs]]. *[http://www.dchomebrew.org/dchakker.shtml DC Hakker] - Similar to Demo Menu but has a better GUI. = Various Tools = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/aspi.zip ASPI Layer Fixer] - Many people have problems with their burners, such as program not even detecting their burner or even not being able to burn at all. I recommend downloading this and using it if you have problems with any burning application on your system. *[http://www.dcemulation.org/files/needed/cdi2nero099.zip CDI2Nero] - Convert Discjuggler images into Nero format. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/CDmage1-01-II.zip CDMage] - This tool can open a CD image and extract files from it. Useful if there aren't any "plain files" for download. *[http://www.dcemulation.org/files/needed/elf2bin.zip Elf2bin] - Converts .elf files into .bin and scrambles/unscrambles bins. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dctool-1.0.exe DCTool 1.0] - A GUI wrapper for Scramble.exe and sh-elf-objcopy.exe by _kRYPT *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_scrambler.zip Pinoy2201's Scrambler] - A scrambler/descrambler & elf2bin converter. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] - An IP.bin logo inserting program. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] - A program that lets you insert your own logo into an IP.BIN. ==Windows Tools== [[DC Anim]] [[Dream Animator]] [[BootDreams]] [[MR Writer]] [[IP.BIN Writer]] [[Region Changer]] [[VMI Writer]] [[1ST_READ.BIN Checker]] ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] 855ec5a8ed4009fcbd4314acb09d2f6796fed817 2493 2481 2023-03-02T08:15:10Z Unknown user 0 /* Windows Tools */ wikitext text/x-wiki __NOTOC__ This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) = Burning Applications = *[http://www.ahead.de/en/index.html#download Nero Burning Rom] - Burns .nrg images. If your burner supports Nero then you should use it. *[http://www.alcohol-software.com/download.php Alcohol 120%] - Burns .cdi images as well as many other formats. *[http://www.padus.com/downloads/demo.php Discjuggler] - Burns .cdi images. Nicknamed Discmangeler because so many people have problems with it. = Selfboot Kits = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dcfactory-0.9.5-FULL.exe DC Factory 0.9.5] - This is one of the best tools you can find for your DC, an all in one burning type program that utilizes scripts and auto updates, you can get the latest headlines from dcemu and everything. A must have for Dreamcast burners everywhere. *[http://www.dchomebrew.org/files/Sbinducr.exe Self Boot Inducer v2.1] - This program will uncompress and build a disc image from .sbi files. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/Selfboot.exe Selfboot] - A selfboot program by burnerO. It's a merger of Selfboot Buddy & Dir2boot. Small in size & easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dssbsfinal.zip DSSBS Final] - Disco Stu's Self Boot Solution. This is a popular DOS-based self-booting utility. It's small and easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_ultimate_selfboot_kitv4final.exe Ultimate Boot Kit V4.0 Final] - This program is very, very easy to use and supports bin2boot (data/data) method and the CDRecord (audio/data) method. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/selfboot.zip The Selfboot Kit Beta 3] - A selfboot kit by Roofus, it will currently create selfbooting CD's for DreamSNES, NesterDC, DCDivx & FreeSCI. *[http://www.dcemulation.org/files/needed/N&DG%204%20dummies%20vr2.exe Nester & DCGNUboy 4 Dummies] - A program put together by Jack_15, this is what he had to say about it: "Well here is the kit I made it is for NesterDC and DcGunuyboy it can uncompress roms that are on .zip and .rar file extensions. you don't have to put any thing in different directories the kit makes them for you!"- Version 2 Uploaded Now *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_quakedc_selfboot_kitv1.zip QuakeDC Selfboot Kit V1] - A program used to selfboot [[Quake|QuakeDC]]. It's another proggy from Pinoy2201 *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dreamboot1-2.zip Dreamboot 1-2] - A selfbooting program called DreamBoot, It has been tried out & it's good & easy to use, so if you've had problems getting programs like DCFactory, DSSBS Final etc. working on your system you might want to give this one a try. = Boot Discs = *[http://www.dchomebrew.org/Demomnu.shtml Demo Menu] - Loads emulators from [[Multisession_CD|multisession CDs]]. *[http://www.dchomebrew.org/dchakker.shtml DC Hakker] - Similar to Demo Menu but has a better GUI. = Various Tools = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/aspi.zip ASPI Layer Fixer] - Many people have problems with their burners, such as program not even detecting their burner or even not being able to burn at all. I recommend downloading this and using it if you have problems with any burning application on your system. *[http://www.dcemulation.org/files/needed/cdi2nero099.zip CDI2Nero] - Convert Discjuggler images into Nero format. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/CDmage1-01-II.zip CDMage] - This tool can open a CD image and extract files from it. Useful if there aren't any "plain files" for download. *[http://www.dcemulation.org/files/needed/elf2bin.zip Elf2bin] - Converts .elf files into .bin and scrambles/unscrambles bins. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dctool-1.0.exe DCTool 1.0] - A GUI wrapper for Scramble.exe and sh-elf-objcopy.exe by _kRYPT *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_scrambler.zip Pinoy2201's Scrambler] - A scrambler/descrambler & elf2bin converter. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] - An IP.bin logo inserting program. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] - A program that lets you insert your own logo into an IP.BIN. ==Windows Tools== [[DC Anim]] [[Dream Animator]] [[BootDreams]] [[MR Writer]] [[IP.BIN Writer]] [[Region Changer]] [[VMI Writer]] [[1ST_READ.BIN Checker]] [[DC Dev ISO]] ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] 9e1e63214db43b74e0d527f772c01637fba512b6 File:Catzdogz 2.jpg 6 1240 2482 2023-03-02T08:09:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Catzdogz 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 38c44f7516a10bcebfa2505b5307745fb70822d3 File:Catzdogz 3.jpg 6 1241 2483 2023-03-02T08:09:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Catzdogz 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 323718949dd2045b819507832ef0ddbe89bd4229 File:Catzdogz 1.jpg 6 1242 2484 2023-03-02T08:09:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Catzdogz 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7a8610ff7ac0220f8132e3810fbdc6ca0fa7b4b6 Catz 'n Dogz 0 1243 2485 2023-03-02T08:09:47Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Catz 'n Dogz |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Catz 'n Dogz |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Catzdogz_3.jpg|thumb|center|300px| Catz 'n Dogz]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/catzndogz.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|William Sams}}} |- style="background:#ffffff" |Type of game || {{{type|Tic-Tac-Toe}}} |- style="background:#ffffff" |Active || {{{isactive|''No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> [[Image:Catzdogz_2.jpg|250px| Catz 'n Dogz]] [[Image:Catzdogz_1.jpg|250px| Catz 'n Dogz]] Catz n' Dogz is just a simple game of Tic Tac Toe / Naughts & Crosses. ==Downloads== * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/catzndogz.zip Plain Files] - ''Unknown release date * Unknown Version - [http://dcemulation.org/1-newsdump/games-demos/CatznDogz.sbi SBI] - ''Unknown release date a5c6e34d460dc000f38c3cd0f1e9646c58012733 File:Srb1 p.png 6 1244 2486 2023-03-02T08:11:34Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Srb1 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 4f5062f7f990fa845ae41d7168a7052daf8fc2fc File:Srb2a p.png 6 1245 2487 2023-03-02T08:11:34Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Srb2a p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 989368be5e080fb6f151f56ecdb95335ed2ab040 File:Srb2b p.png 6 1246 2488 2023-03-02T08:11:34Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Srb2b p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} be60dd6ac803dce7e4cf36fcde88faeee3e6dfdb File:Srbdc p.png 6 1247 2489 2023-03-02T08:11:34Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Srbdc p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 5d575991940350b0136b4f18c6b0da79bac3ec3c Sonic Robo Blast 2 0 1248 2490 2023-03-02T08:11:39Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Sonic Robo Blast 2 |- border="0" cellpadding="2" cellsp..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Sonic Robo Blast 2 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:srbdc_p.png|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.srb2.org/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.09b4}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://web.archive.org/web/20051226194209/http://www.lawrencegearheadz.org/~logan_gba/SRB2/DC/SRB2DC.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[AlamGBC]]}}} |- style="background:#ffffff" |Type of game || {{{type|3rd-Person Platformer}}} |- style="background:#ffffff" |Active || {{{isactive|Yes}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:srb1_p.png|240px| Pic 1]] [[Image:srb2a_p.png|240px| Pic 2]] [[Image:srb2b_p.png|240px| Pic 3]] Sonic Robo Blast 2 is a 3D Sonic fangame based on the DOOM Legacy code base. It was created by a group calling themselves ''Sonic Team Jr, and the Dreamcast version was ported originally by [[AlamGBC]] and LoganGBA. ===Bugs=== * Controller support glitchy. It is recommended that you use a Keyboard. * SDL framerate average of 10fps. * Memory issues cause crashing after playing several consecutive maps. * There's no sound yet. ==Downloads== * SRB2 DC 1.09b4 - [http://web.archive.org/web/20051226194209/http://www.lawrencegearheadz.org/~logan_gba/SRB2/DC/SRB2DC.zip Plainfiles], [http://dreamcast.dcemu.co.uk/files/SRB2DC.zip Alt.] - 10/09/2005 * SRB2 PC 1.09.4 - [http://www.srb2.org/files/FinalDemo1094.exe Win32 Exe]<br />''(Contains needed datafiles)'' * Sonic Robo Blast 2 - [http://www.dcevolution.net/goto.php?id=92 via DCEvolution]<br />''(Ready to burn CDI image)'' * Covers ** By BlazeHedgehog - [http://blazefire.mooglecavern.com/temp/srb2/ Originals] ** By DCEvolution - [http://www.dcevolution.net/covers/view.php?folder=DC%20Evolution%20covers/Sonic%20Robo%20Blast%202&photo=SRB2_Front.png|DCEvolution.net Gallery] ==Links== * [http://mb.srb2.org/showthread.php?t=30779#1 SRB2 Ports List] * [http://www.srb2.org/ SRB2 Official Site] * Discussions ** [http://www.dcemulation.org/phpBB/viewtopic.php?t=72422 DCEmulation Forums] ** [http://mb.srb2.org/showthread.php?t=32727&highlight=dreamcast+port SRB2 Forums ''(latest)''] ==How To Burn SRB2DC== '''Blaze Hedgehog's guide for burning SRB2DC''' (Mostly a ripoff of Digiku's SRB2DC burning guide.) STEP 1: Grab the Elf/bins from the first page of this topic. Extract these to a folder. For example. C:\srb2dc\ STEP 2: Grab the SRB2 1.09 Demo from SRB2.org. Extract the following files to the same directory as the elf\bin (C:\srb2dc\): 3drend.dll, config.cfg, gamedata.dat, drill.dta, music.dta, soar.dta, zim.dta, knux.plr, sonic.plr, tails.plr, srb2.srb, auto.wpn, bomb.wpn, home.wpn, infn.wpn, and rail.wpn. If you have other SRB2 wads you'd like to try with it, put these here, too. (For example, scr_mysticrealm4.wad or sasrb2.wad) STEP 3: Grab [[BootDreams]]. Extract it to something like, C:\bootdreams\. STEP 4: Open Bootdreams (bootdreams.exe). In "Please Select Folder", enter your SRB2DC directory (C:\srb2dc). I used Nero, Track-at-Once, and I left the CD/Volume Label alone. Hit "Create Image". It should tell you there is no IP.bin, either - tell it to create one. STEP 5: When your ISO (in my case, DREAMCAST-TAO.nrg) is created, open your burning program (Nero) and burn. It is reccomended you burn at or under 16x speed, as higher speed burning can cause some problems, depending on your burner. STEP 6: Pop the freshly burned disc into your Dreamcast and enjoy! You can press tab on your Dreamcast Keyboard to bring down the console and play with any of the other WADs you burned with SRB2DC. (addfile *.wad) c8d5d44579dfa116bc5a908a03481ea864f9f06a Freeware homebrew games 0 76 2491 2411 2023-03-02T08:13:45Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[xu4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 436226244eda7374ed855332f1da1853931f0a44 2492 2491 2023-03-02T08:14:01Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 7880814ca081979294e4d0d3a74ceec4ffa7c806 File:Dcdeviso install.png 6 1249 2494 2023-03-02T08:15:34Z Unknown user 0 wikitext text/x-wiki Dcdeviso install a18a35014ac08de90a88fb3850e359f353b77159 DC Dev ISO 0 1250 2495 2023-03-02T08:15:38Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=DC Dev ISO| image=[[Image:Dcdeviso_install.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=R4| downloads=[..." wikitext text/x-wiki {{Infobox_Dev_Information| name=DC Dev ISO| image=[[Image:Dcdeviso_install.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=R4| downloads=[http://dchelp.dcemulation.org/downloads/dcdev/toolchain/DDEr4.rar DiscJuggler image]<br/>[http://dchelp.dcemulation.org/downloads/dcdev/toolchain/DDE_cover.zip CD Case Cover]| release date=3/13/2008| author=[[fackue]]| isactive=Yes }} An easy to install Dreamcast Development Environment using Cygwin. ==What's new== * GDB and Insight included for Debugging * KallistiOS 1.3 updated to svn 561 * dc-load IP\Serial 1.0.4 updated to svn 556 * dc-tool IP\Serial 1.0.4 included in /kos/utils/dctool * scramble included in /kos/utils/scramble * SGE (SDL Graphics Extensions) lib by [[BlueCrab]] * SDL examples by [[Chui]] included * More tutorials (Insight, Updating dc-tool) * Links to most DC related sites * "make" package in Cygwin problems hopefully fixed * Default SDL has been patched to work right * SDL sources and headers reorganized * libGLX by [[Chui]] and updated SDL libs * toolchain rebuilt with the fixed newlib patch * DreamInducer theme fixed ==Credits== * [[BlackAura]] (Cygwin and toolchain help) * [[GPF]] (help with Insight and GDB) * [[MetaFox]] (original DC Cygwin tutorial) * [[Quzar]] (lots of testing) * c99koder (KOS maintainer) * [[Atani]] (KOS maintainer) * [[BlueCrab]] (KOS maintainer) ==History== [http://dchelp.dcemulation.org/downloads/dcdev/toolchain/DDEr3.rar R3] (Nov 27, 2006) * GCC toolchain updated (3.4.6) * KallistiOS updated (1.3 svn 385) - November 26, 2006 * extra KOS libs ** FreeType 2.1.3 by BlueCrab ** lib3ds by SWAT ** lib7z by SWAT ** libkglx by Heinrich Tillack ** liblzma by SWAT ** libmxml by SWAT ** libpbm by SWAT ** libpng 1.2.8 by chui ** SDL 1.2.9 by chui ** SDL_flic by chui ** SDL_gfx by chui ** SDL_image 1.2.4 by chui ** SDL_mixer 1.2.6 by chui ** SDL_prim 0.2.1 by BlueCrab ** SDL_ttf 2.0.7 by SWAT ** SFont by chui ** zlib 1.2.3 by chui * manual setup tutorial * 1ST_READ.BIN Checker, BootDreams, dc-tool GUI and IP.BIN Writer * Dreamcast emulators Chankast (new BIN loader) and DEMUL [http://dchelp.dcemulation.org/downloads/dcdev/toolchain/DDEr2.rar R2] (Dec 07, 2005) * Newest Cygwin installer * KOS 1.3 SVN 287 (December 6, 2005) * dcload IP\Serial 1.0.4 (put this CD in your Dreamcast) * PC tools included (SVN, CodeBlocks, Dev-C++, dctool) * Along with SVN is instruction to updating to the latest KOS SVN * PC Dreamcast emulators included (Chankast and dcemu) * New icon for the autorun program * Now uses 7zip for the tool-chain [http://dchelp.dcemulation.org/downloads/dcdev/deviso/DDEr1.zip R1] (Jun 08, 2005) * Initial release 2b23ba41f8e9d08379ddb57b98210a4d479dcdb0 File:Divi1.jpg 6 1252 2496 2023-03-02T08:18:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Divi1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 3385bf89fd9d701d9a1be9a0c95127170f85343a File:Divi DC back.jpg 6 1251 2497 2023-03-02T08:18:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Divi DC back}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7ecb419da794c3c107c3cccd97c959abc2a25f1b File:Divi DC Front.jpg 6 1253 2498 2023-03-02T08:18:30Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Divi DC Front}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f93be8e2423fa4bb5ae3e4b89851d46b8871703f Divi-dead 0 1254 2499 2023-03-02T08:18:35Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Divi-dead |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Divi-dead |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Dividead10th.png|200px| 10th Anniversary]]<br />[[Image:Divi1.jpg|200px| Game Screenshot]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://foro.tales-tra.com/viewtopic.php?f=73&t=1648 Original (Español)]<br />[http://translate.google.com/translate?hl=en&sl=es&u=http://foro.tales-tra.com/viewtopic.php%3Ff%3D73%26t%3D1648&ei=Lnl4S_3NO8yttgfL7OD1BA&sa=X&oi=translate&ct=result&resnum=1&ved=0CAwQ7gEwAA&prev=/search%3Fq%3Dhttp://foro.tales-tra.com/viewtopic.php%253Ff%253D73%2526t%253D1648%26hl%3Den%26rls%3Dcom.microsoft:en-us Google Translated (English)]}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dividead.tales-tra.com/descargas/dividead-dc-22-10-2008.7z Plain Files]<br />[http://dividead.tales-tra.com/descargas/OGG.7z Music Pack]<br />[http://foro.tales-tra.com/viewtopic.php?f=73&t=1650 Language Pack]<br />[http://sources.tales-tra.com/DIVIDEAD_SRC_RELEASE_22_10_2008.7z Source Code]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/22/2008}}} |- style="background:#ffffff" |Author || {{{author|[[SoyWiz]]}}} |- style="background:#ffffff" |Based on || {{{original|Divi-dead}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes.}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ===Warning! - Contains Mature Content [18+]=== ==History== '''''Via [http://en.wikipedia.org/wiki/Dividead Wikipedia]''''': ''Divi-dead is a Japanese-translated-to English 2D eroge released by C's Ware in 1998. The game's theme falls into the category of adult horror, as it deals with supernatural and sexual topics. Certain images from the game are brutally violent and strange, while others are lighthearted and erotic.'' [[Image:Divi_DC_Front.jpg|200px|middle| Custom Cover - Front]] [[Image:Divi_DC_back.jpg|254px|middle| Custom Cover - Back]] ==Where to find?== This port requires you to have the data files from the original Japanese PC disc, or the later English PC Windows version. You may have luck finding a copy at 'ErogeShop.com' for $9.99, when in stock. You might also have luck finding it at 'Ebay.com', or 'Amazon.com'. *[http://www.erogeshop.com/product_info.php/products_id/1000834 ErogeShop Site (18+ Adult Content)] *[http://shop.ebay.com/?_from=R40&_trksid=m38&_nkw=divi-dead+&_sacat=See-All-Categories Ebay Search] *[http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=divi-dead Amazon Search] 3bd2ff994cd1128c7eed68569524a298e4306ce7 File:Dividead10th.png 6 1255 2500 2023-03-02T08:18:59Z Unknown user 0 wikitext text/x-wiki Dividead10th d945537de5ea1c89da01963d4aedaee193a90377 File:PacMan3d 1.jpg 6 1256 2501 2023-03-02T08:20:15Z Unknown user 0 wikitext text/x-wiki PacMan3d 1 819c45c74509ed4b3a2111e1a546f99982534231 File:PacMan3d 2.jpg 6 1257 2502 2023-03-02T08:20:23Z Unknown user 0 wikitext text/x-wiki PacMan3d 2 38184a65bc80bc5ab24f65ace7da6dcd357df031 DCPacman3D 0 1258 2503 2023-03-02T08:20:28Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | PacMan 3D |- border="0" cellpadding="2" cellspacing="1"..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | PacMan 3D |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:PacMan3d_1.jpg|center|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.brianpostma.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D-src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/22/2004}}} |- style="background:#ffffff" |Author || {{{author|Brian Postma}}} |- style="background:#ffffff" |Type of game || {{{type|PacMan Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> This is the Dreamcast port of Brian Postma's Java applet PacMan 3D game. [[Image:PacMan3d_2.jpg|center|thumb|320px| Play Screen]] <br/> ==Downloads== * ''Unknown version - [http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D.zip Plain Files] - 05/22/2004 * ''Unknown version - [http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D-src.zip Source] - 05/22/2004 6eae9593b1431d1fc2d4a8ef34686c596750f5ee 2504 2503 2023-03-02T08:20:40Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | PacMan 3D |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:PacMan3d_1.jpg|center|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.brianpostma.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D-src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/22/2004}}} |- style="background:#ffffff" |Author || {{{author|Brian Postma}}} |- style="background:#ffffff" |Type of game || {{{type|PacMan Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> This is the Dreamcast port of Brian Postma's Java applet PacMan 3D game. [[File:PacMan3d_2.jpg|center|thumb|320px| Play Screen]] <br/> ==Downloads== * ''Unknown version - [http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D.zip Plain Files] - 05/22/2004 * ''Unknown version - [http://dcemulation.org/1-newsdump/games-demos/pacman_3d/DCPacMan3D-src.zip Source] - 05/22/2004 7e6fc6ea16dbfd9b57d0a534db9330b1cf1dc588 File:Cool1.jpg 6 1259 2505 2023-03-02T08:22:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Cool1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a705416fe6579e105086499f1fd2e9d3be5816c2 File:Cool1 p.jpg 6 1261 2506 2023-03-02T08:22:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Cool1 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 45d71051f0e40e1f70fe4ddb3ca244528255d393 File:Cool herders poster p.jpg 6 1260 2507 2023-03-02T08:22:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Image collected on a PmWiki}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1b19b4a8b7290456f49379def2d60d580636b324 File:Cool2 p.jpg 6 1262 2508 2023-03-02T08:22:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Cool2 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 94209ffd486f456aa6980ffbc7385af8f64e4583 File:Coolscreen p.jpg 6 1263 2509 2023-03-02T08:22:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Coolscreen p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f56f6ee4fcf9bcefababc0688d50b1ffada0d75b File:Coolscreen1 s.jpg 6 1264 2510 2023-03-02T08:22:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Coolscreen1 s}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0e978a32e0c4d29870ff4a8e648fe77ab94999a5 Cool Herders 0 1265 2511 2023-03-02T08:22:55Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Cool Herders |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Cool Herders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Cool1.jpg|thumb|280px| Cool Herders]]}}} |- style="background:#ffffff" |Release Date || {{{release date|12/15/05}}} |- style="background:#ffffff" |Author || {{{author|HarmlessLion}}} |- style="background:#ffffff" |Type of game || {{{type|Multiplayer party}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50/60Hz}}} |} ==History== [[Image:Cool_herders_poster_p.jpg|160px|left|thumb|text-top| Cool Herders Promo Poster]] One of the few independent Dreamcast games that were released commercialy, this title is available through [http://www.goatstore.com/info.php?id=810012 The GOAT Store]. Cool Herders was originally conceived as a quick demo game from ''Moving Target Software Design'' (now defunct), for inclusion on a demo CD being produced by [[Cryptic Allusion]] for distribution at E3 in 2002. The demo was conceived and by Binky, who did all artwork, and developed by Tursi in only three weeks. The CD itself, DC Tonic, included demos from a number of groups and was generally considered a success. Cool Herders itself is a party game written for [[KallistiOS|KOS]], in which four herders armed with lightning-powered crooks attempt to round up the most rampant sheep, stealing them from others if necessary. The DC Tonic version of the game did not support powerups, although the final release of the demo did include speed and lightning power ups. The play mechanics are simple: d-pad or analog stick to move your herder, and A,B,X or Y to fire lightning. Lightning stuns sheep, destroys environment (to reveal powerups), and zaps other herders, causing them to lose sheep. Trivia: the sheep sounds in the game are loving recordings of Flossie, the prettiest sheep in the world! ==The Demos== ===Demo 1=== This game was originally created for the Dreamcast specifically for inclusion as a demo on the DC Tonic E3 Demo CD. The project was abandoned in 2003, but picked up again in late 2004 and now it has been completed for commercial release through GOAT Store Publishing. [[Image:Cool1_p.jpg|150px| Screen 1]] [[Image:Cool2_p.jpg|150px| Screen 2]] ===Demo 2=== The second demo was released on March, 31th in 2006: This download is a new demo based on the released code, and is no longer related to the old version from DC Tonic. Notes - This is a very simplified demo - it includes only the New Zealand multiplayer stages (3 in total) and 3 selectable players. [[Image:Coolscreen_p.jpg|150px| Screen 1]] [[Image:Coolscreen1_s.jpg|150px| Screen 2]] ==Downloads== * [http://www.harmlesslion.com/software/herders Demo 2] ==Links== * [http://play.harmlesslion.com/products/cool.htm Official Website] * [http://www.goatstore.com/info.php?id=810012 GOAT Store Product Page] dd42cbf331f30c09fa3543bb74a20f5a99c53d35 Old tools 0 195 2512 2493 2023-03-02T08:34:40Z Unknown user 0 /* Windows Tools */ wikitext text/x-wiki __NOTOC__ This page serves as a placeholder/index for old tools hosted by DCEmulation that need proper archival. [[Mac tools]] -- A Mac subpage. *[[:File:E-selfbt.zip|e-selfbt]] - the very original Echelon selfboot toolkit *[[:File:Cdmage.zip|CDMage 1.01.5 and 1.02.1b]] - Windows GUI program useful for checking the integrity of ISOs *[[:File:Ipbin4win.zip|IPBIN4WIN 0.8b by Dextrose]] - Windows GUI IPBIN editor *[[:File:Ip2post.rar|IP2POST utility]] - batch file, drag/drop IP.BIN/IP0000.BIN/track03.iso of a Dreamcast disc to print its metadata to a text file, useful for making posts on [[Dumpcast]] *[[:File:Makesort.zip|makesort]] - Windows utility to convert isobuster sort files to cdrecord format *[[:File:Dccuegen.zip|dccuegen.bat]] - quick and crude cuesheet generator batch file for dreamcast dumps (cuesheet can be mounted and loaded into ISOBuster for extraction/manipulation of GD high density) *[[:File:Dcdump.zip|dcdump.sh]] - bash script for automating dumping GD-ROMs with httpd-ack on Win10 (WSLv1/v2), macOS, or Linux *[[:File:Gdhack.zip|gdhack]] - Windows binhacking utilities (cdda, dahack, hack3) *[[:File:Gdhack4.zip|gdhack4]] - Windows binhacking utility (hack4) = Burning Applications = *[http://www.ahead.de/en/index.html#download Nero Burning Rom] - Burns .nrg images. If your burner supports Nero then you should use it. *[http://www.alcohol-software.com/download.php Alcohol 120%] - Burns .cdi images as well as many other formats. *[http://www.padus.com/downloads/demo.php Discjuggler] - Burns .cdi images. Nicknamed Discmangeler because so many people have problems with it. = Selfboot Kits = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dcfactory-0.9.5-FULL.exe DC Factory 0.9.5] - This is one of the best tools you can find for your DC, an all in one burning type program that utilizes scripts and auto updates, you can get the latest headlines from dcemu and everything. A must have for Dreamcast burners everywhere. *[http://www.dchomebrew.org/files/Sbinducr.exe Self Boot Inducer v2.1] - This program will uncompress and build a disc image from .sbi files. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/Selfboot.exe Selfboot] - A selfboot program by burnerO. It's a merger of Selfboot Buddy & Dir2boot. Small in size & easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dssbsfinal.zip DSSBS Final] - Disco Stu's Self Boot Solution. This is a popular DOS-based self-booting utility. It's small and easy to use. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_ultimate_selfboot_kitv4final.exe Ultimate Boot Kit V4.0 Final] - This program is very, very easy to use and supports bin2boot (data/data) method and the CDRecord (audio/data) method. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/selfboot.zip The Selfboot Kit Beta 3] - A selfboot kit by Roofus, it will currently create selfbooting CD's for DreamSNES, NesterDC, DCDivx & FreeSCI. *[http://www.dcemulation.org/files/needed/N&DG%204%20dummies%20vr2.exe Nester & DCGNUboy 4 Dummies] - A program put together by Jack_15, this is what he had to say about it: "Well here is the kit I made it is for NesterDC and DcGunuyboy it can uncompress roms that are on .zip and .rar file extensions. you don't have to put any thing in different directories the kit makes them for you!"- Version 2 Uploaded Now *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201_quakedc_selfboot_kitv1.zip QuakeDC Selfboot Kit V1] - A program used to selfboot [[Quake|QuakeDC]]. It's another proggy from Pinoy2201 *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dreamboot1-2.zip Dreamboot 1-2] - A selfbooting program called DreamBoot, It has been tried out & it's good & easy to use, so if you've had problems getting programs like DCFactory, DSSBS Final etc. working on your system you might want to give this one a try. = Boot Discs = *[http://www.dchomebrew.org/Demomnu.shtml Demo Menu] - Loads emulators from [[Multisession_CD|multisession CDs]]. *[http://www.dchomebrew.org/dchakker.shtml DC Hakker] - Similar to Demo Menu but has a better GUI. = Various Tools = *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/aspi.zip ASPI Layer Fixer] - Many people have problems with their burners, such as program not even detecting their burner or even not being able to burn at all. I recommend downloading this and using it if you have problems with any burning application on your system. *[http://www.dcemulation.org/files/needed/cdi2nero099.zip CDI2Nero] - Convert Discjuggler images into Nero format. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/CDmage1-01-II.zip CDMage] - This tool can open a CD image and extract files from it. Useful if there aren't any "plain files" for download. *[http://www.dcemulation.org/files/needed/elf2bin.zip Elf2bin] - Converts .elf files into .bin and scrambles/unscrambles bins. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/dctool-1.0.exe DCTool 1.0] - A GUI wrapper for Scramble.exe and sh-elf-objcopy.exe by _kRYPT *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_scrambler.zip Pinoy2201's Scrambler] - A scrambler/descrambler & elf2bin converter. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] - An IP.bin logo inserting program. *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] - A program that lets you insert your own logo into an IP.BIN. ==Windows Tools== [[DC Anim]] [[Dream Animator]] [[BootDreams]] [[MR Writer]] [[IP.BIN Writer]] [[Region Changer]] [[VMI Writer]] [[1ST_READ.BIN Checker]] [[DC Dev ISO]] [[CodeBlocks DC Dev]] ==MR Image insertion programs== ===Windows=== *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/jsilibeta3.exe Jack_15's Simple IP.bin Logo Inserter Beta 3] *[http://www.dcemulation.org/dl/dl.php3?url=files/needed/pinoy2201s_logo_insert.zip Pinoy2201's Logo Insert] ===Mac OSX=== *[http://dcemulation.org/1-files/tools/pc/mac/MDTS122.tar.gz Mac Dream Tool Services] ===MR Logo Downloads=== *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCDev.mr DCDev] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation.mr DCEmulation] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(Joey2cool).mr DCEmulation+(Joey2cool)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(melancholy).mr DCEmulation+(melancholy)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(nuclear_winter).mr DCEmulation+(nuclear_winter)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(SprkFade).mr DCEmulation+(SprkFade)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(tenchimasaki).mr DCEmulation+(tenchimasaki)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulation+(VampireHawke).mr DCEmulation+(VampireHawke)] *[http://dcemulation.org/covers/index.cgi?get&Themes/MR%20Files/DCEmulaton+Logos.zip DCEmulation Logos] *[http://dcemulation.org/other/mr_images/MRImages.zip Package of 32 MR images (Game & Emulator based)] e86f66086375a00752b79d5a25d31bf901eb8482 File:CbdcdevR2-01.png 6 1266 2513 2023-03-02T08:35:10Z Unknown user 0 wikitext text/x-wiki CbdcdevR2-01 5c8e649f9f3ae6dd23b676672f878b35eaa23cb7 CodeBlocks DC Dev 0 1267 2514 2023-03-02T08:35:12Z Unknown user 0 Created page with "{{Infobox_Dev_Information| name=Code::Blocks DC Dev| image=[[Image:CbdcdevR2-01.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=R2| downlo..." wikitext text/x-wiki {{Infobox_Dev_Information| name=Code::Blocks DC Dev| image=[[Image:CbdcdevR2-01.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=R2| downloads=[http://dchelp.dcemulation.org/downloads/dcdev/toolchain/CodeBlocks_DCDev_R2.exe Installer]<br/>| release date=3/14/2008| author=fackue| isactive=Yes }} This development environment installs on top of Code::Blocks using a Nullsoft installer and a automatic configurator that configures the Dreamcast compilers. Officially, Code::Blocks 8.02 is only supported. ==What's new== * GDB is setup and working * bin2o program (located in the "Tools" menu) * MinGW 3.4.6 toolchain * KOS updated to revision 561 * KOS built in MinGW * dc-tool IP and Serial included and built in MinGW (/kos/utils/dc-tool) * scramble has been included (/kos/utils/scramble) * SDL headers and lib issues has been resolved * Option to compress the toolchain using UPX ==Credits== * [[JMD]] (R1 used his bin2odc) * pnpbios (original CodeBlocks for DC tutorial) * Harley (dc-tool IP MinGW) * [[GPF]] (help with GDB) * [[BlueCrab]] (help with MinGW toolchain) * [[BlackAura]] (used his MinGW build script as reference) ==History== [http://dchelp.dcemulation.org/downloads/dcdev/toolchain/CodeBlocks_DCDev_R1.exe R1] (Sept 09, 2007) * Initial release dbb22f6eb2834e87c150a4b7bf8183eb172812bd 2515 2514 2023-03-02T08:35:17Z Unknown user 0 wikitext text/x-wiki {{Infobox_Dev_Information| name=Code::Blocks DC Dev| image=[[File:CbdcdevR2-01.png|center|250px]]| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=R2| downloads=[http://dchelp.dcemulation.org/downloads/dcdev/toolchain/CodeBlocks_DCDev_R2.exe Installer]<br/>| release date=3/14/2008| author=fackue| isactive=Yes }} This development environment installs on top of Code::Blocks using a Nullsoft installer and a automatic configurator that configures the Dreamcast compilers. Officially, Code::Blocks 8.02 is only supported. ==What's new== * GDB is setup and working * bin2o program (located in the "Tools" menu) * MinGW 3.4.6 toolchain * KOS updated to revision 561 * KOS built in MinGW * dc-tool IP and Serial included and built in MinGW (/kos/utils/dc-tool) * scramble has been included (/kos/utils/scramble) * SDL headers and lib issues has been resolved * Option to compress the toolchain using UPX ==Credits== * [[JMD]] (R1 used his bin2odc) * pnpbios (original CodeBlocks for DC tutorial) * Harley (dc-tool IP MinGW) * [[GPF]] (help with GDB) * [[BlueCrab]] (help with MinGW toolchain) * [[BlackAura]] (used his MinGW build script as reference) ==History== [http://dchelp.dcemulation.org/downloads/dcdev/toolchain/CodeBlocks_DCDev_R1.exe R1] (Sept 09, 2007) * Initial release 133b637e11d44911b5f9ae58095c996cfdd25cb3 File:Lotr 1.jpg 6 1268 2516 2023-03-02T17:56:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lotr 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} dbfeff664c0ff3df771476e221fab9dd9a39d5ef File:Lotr 2.jpg 6 1270 2517 2023-03-02T17:56:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lotr 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 849f509e714f50f83e5389239ece07fb9226f8ab File:Lotr 3.jpg 6 1269 2518 2023-03-02T17:56:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lotr 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} dee6bd652429d5ec170a92550368af78bc37f0b2 File:Lotr 4.jpg 6 1271 2519 2023-03-02T17:56:44Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lotr 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 099e40a52b5c22fa554b06f9bdb34a7627c95237 The Lord of the Rings 0 1272 2520 2023-03-02T17:56:46Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Lord of the Rings |- border="0" cellpadding="2" cel..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Lord of the Rings |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Lotr_1.jpg|thumb|center|280px| Volume 1]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/lord_rings/lotrDCfull.rar Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/??/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|The Lord of the Rings, Vol 1<br/>by [http://www.interplay.com/ Interplay Productions]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== <br/> This is a development version of The Lord of the Rings game engine which plays famous Interplays game The Lord of the Rings. [[Image:Lotr_2.jpg|250px| Lord of the Rings]] [[Image:Lotr_3.jpg|250px| Lord of the Rings]] [[Image:Lotr_4.jpg|250px| Lord of the Rings]] ===Features=== * Requires dreamcast keyboard to play * D-pad implemented for movement and cutscenes only. ===Controls=== * Arrows → move leader * Space → main menu * Escape → exit menu, skip cartoon * O → options menu * A → attack * V → view * G → get * U → use * S → skills * M → magic * T → talk * L → select leader * C → choose * X → exit menu ==Downloads== * lotrDCfull - [http://dcemulation.org/1-newsdump/games-demos/lord_rings/lotrDCfull.rar Plain Files] - 04/??/2005<br/>''(requires DOS data files)'' * lotrDCdemo - [http://dcemulation.org/1-newsdump/games-demos/lord_rings/lotrDCdemo.rar Plain Files] - 04/??/2005<br/>''(demo files included)'' * lotrDC - [http://dcemulation.org/1-newsdump/games-demos/lord_rings/lord-0.6.1src.rar Source] - 04/??/2005<br/>''(requires libxml2 lib)'' fce5d9421ffcf0630bfd03033a5bc7fa6123ea83 2521 2520 2023-03-02T17:57:04Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Lord of the Rings |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Lotr_1.jpg|thumb|center|280px| Volume 1]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/lord_rings/lotrDCfull.rar Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/??/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|The Lord of the Rings, Vol 1<br/>by [http://www.interplay.com/ Interplay Productions]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== <br/> This is a development version of The Lord of the Rings game engine which plays famous Interplays game The Lord of the Rings. [[File:Lotr_2.jpg|250px| Lord of the Rings]] [[File:Lotr_3.jpg|250px| Lord of the Rings]] [[File:Lotr_4.jpg|250px| Lord of the Rings]] ===Features=== * Requires dreamcast keyboard to play * D-pad implemented for movement and cutscenes only. ===Controls=== * Arrows → move leader * Space → main menu * Escape → exit menu, skip cartoon * O → options menu * A → attack * V → view * G → get * U → use * S → skills * M → magic * T → talk * L → select leader * C → choose * X → exit menu ==Downloads== * lotrDCfull - [http://dcemulation.org/1-newsdump/games-demos/lord_rings/lotrDCfull.rar Plain Files] - 04/??/2005<br/>''(requires DOS data files)'' * lotrDCdemo - [http://dcemulation.org/1-newsdump/games-demos/lord_rings/lotrDCdemo.rar Plain Files] - 04/??/2005<br/>''(demo files included)'' * lotrDC - [http://dcemulation.org/1-newsdump/games-demos/lord_rings/lord-0.6.1src.rar Source] - 04/??/2005<br/>''(requires libxml2 lib)'' fdde4ea161fdafe4e78ff727c4a7afb2eeeb672e File:Echo 2.jpg 6 1275 2522 2023-03-02T17:58:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Echo 2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a94f193d36dc2600888472d9e075c8c609763168 File:Echo 1.jpg 6 1273 2523 2023-03-02T17:58:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Echo 1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 18e594659922fca2ff8e66dd1517a8beed4c0e80 File:Echo 3.jpg 6 1274 2524 2023-03-02T17:58:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Echo 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} cb628205e469211f6aa3f03daab79e6d6b14bdd6 File:Echo 5.jpg 6 1277 2525 2023-03-02T17:58:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Echo 5}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} bd2b880734d19f32ddb1af89cd453598aa50220a File:Echo 6.jpg 6 1276 2526 2023-03-02T17:58:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Echo 6}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 334358208f3c523bed89a3993864089eeeb4fd43 File:Echo 4.jpg 6 1278 2527 2023-03-02T17:58:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Echo 4}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8bd74faa49391573ada15a73cebb96818864dd45 Echo's Quest 0 1279 2528 2023-03-02T17:59:00Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Echo's Quest |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Echo's Quest |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Echo_1.jpg|thumb|center|250px| Echo's Quest]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20021021091614/consolevision.com/trilinear/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/echo_quest/Echos_Quest.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/21/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|Platformer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== [[Image:Echo_4.jpg|250px| Echo's Quest]] [[Image:Echo_2.jpg|250px| Echo's Quest]] [[Image:Echo_3.jpg|250px| Echo's Quest]] '' 'Echo's platforming adventure last seen on the GBA and TG16 comes to the DC in full 2.5d glory.' ===Controls=== * Start - to begin game and enter menu(without quitting) * Start+Y - quit * Stick - Tilt overworld view * RTrigger - zoom in * A - jump/select menu item(to quit) * B - exit menu(without quitting) * X - take screenshot(if using BBA or cable) * pad - move Overworld: * Completed levels are blue, incomplete levels are red, levels not yet built are gray. Game: * To complete a level, find the goal Menu: * Unlock/Relock Overworld - unlocking the overworld allows you to move past levels you have not completed * See your top score (L/R to select level) * Quit - quit game [[Image:Echo_6.jpg|250px| Echo's Quest]] [[Image:Echo_5.jpg|250px| Echo's Quest]] ==Downloads== * Beta 1.0 - [http://dcemulation.org/1-newsdump/games-demos/echo_quest/Echos_Quest.zip Plain Files] - 05/21/2002 * Beta 1.0 - [http://dcemulation.org/1-newsdump/games-demos/echo_quest/EchosQuest.sbi SBI] - 05/21/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] 00dc291e0a7027151bbd803d87c902b19c7e616c File:BubbleMachine1.jpg 6 1280 2529 2023-03-02T17:59:56Z Unknown user 0 wikitext text/x-wiki BubbleMachine1 30754f296d905b9bc2b2ee4582fcce37a777fccb File:BubbleMachine2.jpg 6 1281 2530 2023-03-02T18:00:02Z Unknown user 0 wikitext text/x-wiki BubbleMachine2 7c2b8d92188843ba4640eb1a231f1d92d4fdb0de The Bubble Machine 0 1282 2531 2023-03-02T18:00:07Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Bubble Machine |- border="0" cellpadding="2" cellsp..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Bubble Machine |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:BubbleMachine1.jpg|center|thumb|300px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/puzzbobl.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Vinic Games}}} |- style="background:#ffffff" |Type of game || {{{type|Puzzle Bobble Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Vinic Games' Puzzle Bobble clone adapted to Dreamcast Fenix by DCEmu's ''Wraggster''. [[Image:BubbleMachine2.jpg|center|320px| Title Screen]] ==Downloads== * ''Unknown version'' - [http://dcemulation.org/1-newsdump/games-demos/puzzbobl.zip Plain Files] - ''Unknown release date'' 89c1a265bfc2da6cc51d768fefb0af82e6796585 File:Beatsofrage.gif 6 1283 2532 2023-03-02T18:00:42Z Unknown user 0 wikitext text/x-wiki Beatsofrage d0e34bb3b4cdb7d73461ff9820f059c26ecbb24e Beats of Rage 0 1284 2533 2023-03-02T18:00:45Z Unknown user 0 Created page with "{{Infobox_Game_Information| name=Beats of Rage| image=[[Image:beatsofrage.gif|center]]| homepage=[http://www.senileteam.com/beatsofrage.html Homepage]| version=1.0| downl..." wikitext text/x-wiki {{Infobox_Game_Information| name=Beats of Rage| image=[[Image:beatsofrage.gif|center]]| homepage=[http://www.senileteam.com/beatsofrage.html Homepage]| version=1.0| downloads=[http://www.maturion.de/dateien/spiele/bordc.rar DiscJuggler image] | release date=2003| author=[[Senile Team]]| type=2D fighting| refreshrate=60Hz| isactive=No }} Beats of Rage is a freeware open source video game and moddable game engine made by Senile Team and inspired by Sega's classic Streets of Rage series. From Senile Team, the creators of Beats of Rage: ''As fans of the 'Streets of Rage' series that originally appeared on the SEGA megadrive/genesis, we always wanted to see streets of rage 4. But the waiting proved futile, and streets of rage 4 never came. That's why we tried to correct this mistake and fill the void by making the ultimate tribute to Streets of Rage: Beats of Rage!'' The source code of Beats of Rage later was released and other programmers continued developing the engine as [[OpenBOR]]. ==Links== *[http://www.senileteam.com/beatsofrage.html Beats of Rage @ SenileTeam.com] *[http://www.lavalit.com LavaLit.com - OpenBOR modding community] [[Category:Homebrew game]] e64eb6d6cd2fdac49bcc078f694a3c77a0b9a206 2534 2533 2023-03-02T18:00:50Z Unknown user 0 wikitext text/x-wiki {{Infobox_Game_Information| name=Beats of Rage| image=[[File:beatsofrage.gif|center]]| homepage=[http://www.senileteam.com/beatsofrage.html Homepage]| version=1.0| downloads=[http://www.maturion.de/dateien/spiele/bordc.rar DiscJuggler image] | release date=2003| author=[[Senile Team]]| type=2D fighting| refreshrate=60Hz| isactive=No }} Beats of Rage is a freeware open source video game and moddable game engine made by Senile Team and inspired by Sega's classic Streets of Rage series. From Senile Team, the creators of Beats of Rage: ''As fans of the 'Streets of Rage' series that originally appeared on the SEGA megadrive/genesis, we always wanted to see streets of rage 4. But the waiting proved futile, and streets of rage 4 never came. That's why we tried to correct this mistake and fill the void by making the ultimate tribute to Streets of Rage: Beats of Rage!'' The source code of Beats of Rage later was released and other programmers continued developing the engine as [[OpenBOR]]. ==Links== *[http://www.senileteam.com/beatsofrage.html Beats of Rage @ SenileTeam.com] *[http://www.lavalit.com LavaLit.com - OpenBOR modding community] [[Category:Homebrew game]] a07261579b2014235c4045193536b6411f4b3323 File:AgeOfTheBeast01 p.gif 6 1285 2535 2023-03-02T18:02:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=AgeOfTheBeast01 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b545ad71967f6f11c83bcb6e91140936d9f60159 File:AgeOfTheBeast03 p.png 6 1286 2536 2023-03-02T18:02:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=AgeOfTheBeast03 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 860d7077303edbfa6fe84b114b2692200a35fad7 File:AgeOfTheBeast02 p.png 6 1287 2537 2023-03-02T18:02:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=AgeOfTheBeast02 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 5d906602a105fcb26717ad6e086b5bee830d6b38 File:AgeOfTheBeast05 p.png 6 1288 2538 2023-03-02T18:02:47Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=AgeOfTheBeast05 p}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1e3b6eb49ffa614790d56a2ae0a7b43b3079c9fc Age of the Beast 0 1289 2539 2023-03-02T18:02:58Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|Age of the Beast}}} |- border="0" cellpadding="..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|Age of the Beast}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:AgeOfTheBeast01_p.gif|thumb]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.senileteam.com Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''N/A}}} |- style="background:#ffffff" |Downloads || {{{downloads|''N/A}}} |- style="background:#ffffff" |Release Date || {{{release date|TBA}}} |- style="background:#ffffff" |Author || {{{author|[[Senile Team]]}}} |- style="background:#ffffff" |Type of game || {{{type|Beat'em up }}} |- style="background:#ffffff" |Active || {{{isactive|Yes}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''N/A}}} |} [[Senile Team]]'s next Dreamcast project will be a swords & sorcery beat'em up game. Age of the Beast will be the spiritual successor of their first production, [[Beats of Rage]], but with all original graphics and an entirely rewritten, overhauled game engine. ==Development== The game entered development as downloadable freeware just like BOR however a '''Special''' commercial edition with Dreamcast-exclusive extra levels & characters was announced in 2006 at the MidWest Gaming Classic, in an [[Roel Van Mastbergen interview|interview with us on 9th September 2010 Senile Team announced the freeware version has been cancelled]], attributed reasons inclueded the evolution of the openBOR engine and the growing complexity of the AOTB engine with more specific features. ===Confirmed Features=== * Up to 4 players simultaneously * Support for wide-screen TV sets as well as normal ones * 4 heroes (+ additional secret characters) * Moves per character: ~40 (!) * Max. animations per character: ~100 * True-colour graphics * Alpha blending and other graphical effects * Animated backgrounds * Original character designs * 16-bit, 44100 KHz stereo soundtrack * All-new, original soundtrack composed by Ben "Black Device" Boahene * Moddable engine will be released as freeware, so expect many free mods! * Platforms: Dreamcast, PC, PlayStation 2, most likely GP2x and Xbox, and maybe more! * Age of the Beast will be Open Source (GPL) software ===Screenshots=== Early Screens from AOTB. [[Image:AgeOfTheBeast02_p.png]] [[Image:AgeOfTheBeast05_p.png]] [[Image:AgeOfTheBeast03_p.png]] ===Videos=== ---- * [http://video.google.com/videoplay?docid=-875234034914557018&q=age+of+the+beast Preview 1 Video] * [http://video.google.com/videoplay?docid=1823713495289029806&q=age+of+the+beast Preview 2 Video] ===Links=== *[http://www.senileteam.com/games.php#aotb Senile Team's Age of the Beast section] *[http://www.senileteam.com/forum.php?area=3 Age of the Beast Forum] e334467fff829c3ead5224e05375a6d56c42a96e File:Senile Team Logo.jpg 6 1290 2540 2023-03-02T18:04:02Z Unknown user 0 wikitext text/x-wiki Senile Team Logo ad4d34cc984d7ecb993f745fbbae05770634df78 Senile Team 0 1291 2541 2023-03-02T18:04:09Z Unknown user 0 Created page with "[[Image:Senile Team Logo.jpg|300px|left]] == History == Senile Team was born in 2003 with the creation of [[Beats of Rage]]. Originally intended as nothing more than a fun l..." wikitext text/x-wiki [[Image:Senile Team Logo.jpg|300px|left]] == History == Senile Team was born in 2003 with the creation of [[Beats of Rage]]. Originally intended as nothing more than a fun little private project, Beats of Rage soon became a very popular game which was ported to Dreamcast by [[Neil Corlett]]. Following this success, the team began to work on the ambitious [[Age of the Beast]] project. However, this project was temporarily interrupted to complete [[Rush Rush Rally Racing]], which was released in 2009 and received very positive reviews. ===Why the name "Senile Team"? === ''This is probably our most-heard question. We only found that we needed a name for ourselves when Beats of Rage was almost finished, but we didn't have to think for a very long time about what it should be. We had already been using the name "Senile" for various things for years. It was originally conceived as the name for a mailing list. All the names that actually made sense were already taken, but after typing a few random words it turned out that "senile" was still available. As a name for our team it is far from meaningless though. The word "Senile" hints at old age, thus matching our interest in old-school gaming. And since senile dementia affects the memory (amongst other things), our motto became "proudly forgetting ten years of video games history". Meanwhile that should probably be about fifteen years.'' Quoted from Senile Team's ABOUT page. ===Members=== Roel (credited as "Opla" in BoR) The team's chieftain. Does most of the game design, programming and artwork. www.roelvanmastbergen.nl Jeroen (credited as "Leila" in BoR) Level editing, communications and quality control. Albatross 3D artist and animation sequence editor. Ben "Black Device" Boahene Senile Team's composer, who did the excellent soundtrack for Rush Rush Rally Racing and is currently working on Age of the Beast. Liënne ten Kate Liënne did some colouring work for Rush Rush Rally Racing, and will help finish Age of the Beast with her animator's skills. www.lienne.nl ===Former Members=== Neil Corlett ==Games== [[Beats of Rage]] - 2003 [[Rush Rush Rally Racing]] - 2009 [[Age of the Beast - 'When It's Done' == See Also == [[Roel Van Mastbergen interview| Interview of Roel Mastbergen from Senile Team 9/9/10]] == External Links == *[http://www.senileteam.com/ SenileTeam.com - Official Website] *[http://www.redspotgames.com/ RedSpotGames - Publisher Website] 45125b0ad22c08806cffd4087b028504f8af8764 QuakeDC 0 1292 2542 2023-03-02T18:04:40Z Unknown user 0 Created page with "Developer: Titan Studios Version: 1.0 Last Updated: January 14, 2001 Description: A port of the original Quake to the Dreamcast. [http://www.dcemulation.org/files/softw..." wikitext text/x-wiki Developer: Titan Studios Version: 1.0 Last Updated: January 14, 2001 Description: A port of the original Quake to the Dreamcast. [http://www.dcemulation.org/files/software/quake_sw.rar Plain Files (1/3)] [http://www.dcemulation.org/files/software/quake_sw.r00 Plain Files (2/3)] [http://www.dcemulation.org/files/software/quake_sw.r01 Plain Files (3/3)] [http://quakedev.dcemulation.org/ip.bin IP.BIN file] Mods (probably a very incomplete list, check the forums Or QuakeDev for more): [http://www.dcemulation.org/files/software/JoyMenu2.zip Joy Menu 2] [http://www.dcemulation.org/files/software/raptordc.zip Raptor] [http://www.dcemulation.org/files/software/reaper2dc01.zip Reaper Bots] [http://www.dcemulation.org/files/software/simpsonsdc.zip Simpsons] [http://www.dcemulation.org/files/software/fbxdc.zip FBX DC] 4d2391055ebc8a191d3830a3a97d13da59bddbb9 File:Quake 2.jpg 6 1293 2543 2023-03-02T18:05:30Z Unknown user 0 wikitext text/x-wiki Quake 2 bf61ef0a499476d83bf31872b76a439030045228 File:Quake 1.jpg 6 1294 2544 2023-03-02T18:05:36Z Unknown user 0 wikitext text/x-wiki Quake 1 1e5ed73032b78af5d0a703c60a0a37e668b60b9b DCQuake 0 1295 2545 2023-03-02T18:05:40Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | DCQuake |- border="0" cellpadding="2" cellspacing="1" a..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | DCQuake |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Quake_1.jpg|thumb|280px| Game Screen]][[Image:Quake_2.jpg|thumb|280px| Load Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://sourceforge.net/projects/dcquake/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|2nd}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/ports/DCQuake/dcquake-2002-08-11-bin.zip Plain Files]<br/>[http://sourceforge.net/projects/dcquake/files/quake/shareware/quake106.zip Quake Shareware]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/11/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[ftp://ftp.idsoftware.com/idstuff/source/q1source.zip Quake 1 Source]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|No}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== This is Bero's port of Quake to the Dreamcast. You should set joypad config in options/customize control before starting game. ===Status=== * working quake and glquake * quake: sometimes buggy color. * glquake: transparency bug * both run with shareware version data files or commercial CD-ROM. * MOD/TC can work. * full control using pad (except console) , and mouse,keyboard support * sound * save to visual memory with zlib compression and icon * no cd-da music, unless from PC via DC cable * no network ===Controls=== Menu: * UP/DOWN → select mod * L-TRIG/R-TRIG → scroll description text * START/A → start game * Y → disk change Game: Joystick ↔ Keyboard ↔ Default bind * UP ↔ UP ↔ FORWARD * DOWN ↔ DOWN ↔ BACK * LEFT ↔ LEFT ↔ TURN LEFT * RIGHT ↔ RIGHT ↔ TURN RIGHT * A ↔ ENTER ↔ JUMP * B ↔ SPACE ↔ JUMP * X ↔ none ↔ none * Y ↔ Y ↔ none * R-TRIG ↔ CTRL ↔ ATTACK * L-TRIG ↔ ALT ↔ SIDESTEP * analog ↔ move ==Setup== burned Quake shareware version: \QUAKE_SW +- ID1 +- glquake (optional*) +- PAK0.PAK burned Quake commercial version full install: \QUAKE +- ID1 | +- glquake (optional*) | +- PAK0.PAK | +- PAK1.PAK | +- quakeXX.pcx or quakeXX.tga (optional) +- other mod (optional) +- other mod (optional) +- games.lst (optional) (*) glquake directory is generated when you run glquake on PC, or mkdir by hand and run under dcload-ip. If this directory exists, loading is faster. Quake commercial version CD-ROM: \Data +- ID1 +- glquake +- PAK0.PAK +- PAK1.PAK ==Downloads== * 2nd Release - [http://dcemulation.org/1-newsdump/ports/DCQuake/dcquake-2002-08-11-bin.zip Plain Files] - 08/11/2002 * 1st Release - [http://dcemulation.org/1-newsdump/ports/DCQuake/dcquake-2002-07-24-bin.zip Plain Files] - 07/24/2002 * 1st Release - [http://dcemulation.org/1-newsdump/ports/DCQuake/dcquake-2002-07-24.tar.gz Source] - 07/24/2002 * Quake Shareware - [http://sourceforge.net/projects/dcquake/files/quake/shareware/quake106.zip Zipfile] - 08/03/2002 262f1e96772a05216fcec8671f31a53dc632925e File:DynamitePromo1 p.png 6 1296 2546 2023-03-02T18:06:42Z Unknown user 0 wikitext text/x-wiki DynamitePromo1 p f48b17e7e793de075c1c9c5c8f887623e360aee7 File:Aliced platform1.jpg 6 1297 2547 2023-03-02T18:06:59Z Unknown user 0 wikitext text/x-wiki Aliced platform1 0c25bc34d9b748574331d8c5f78496473a01beda Alice Dreams 0 1298 2548 2023-03-02T18:07:09Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Alice Dreams |- border="0" cellpadding="2" cellspacing=..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Alice Dreams |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Aliced platform1.jpg|thumb|center|320px]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://archives.dcemulation.org/www.alicedreams.com/www.alicedreams.com/HomePageFR.htm Home Page]<br />(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|3.0 (Demo)}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://archives.dcemulation.org/www.alicedreams.com/www.alicedreams.com/aliced3.zip CDI]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/25/2005}}} |- style="background:#ffffff" |Author || {{{author|[[patbier]]<br />/[[poche]]}}} |- style="background:#ffffff" |Type of game || {{{type|Platformer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50Hz}}} |} ==History== Inspired by Lewis Carol's novel, Alice Dreams by Patbier and Pouche is one of the best homebrewn games ever created for a console. It plays like a mix of an adventure game (with speech in English and French during dialogs, subtitles are available for a lot of different languages) and a Jump 'n Run. *Programmer: Julien Desquenne (patbier) *Graphician: Nicolas Pochet (poche) *Musician: Philippe Vendi ==Latest News== * Project was abandoned, and game was never finished * [[Image:DynamitePromo1_p.png]] "For the Dream On Contest 3, we have developed a complete game starting from the mini game [[Dynamite Dreams]]. (Note: Dynamite Dreams was a bonus game in Alice Dreams v3) At the present time, the game contains 8 different maps and a challenge mode. You certainly think that you have already seen too much bombermen, and that our DC already owns an excellent one, but we didn't stop there. Our game owns unique multiplayer modes. Especially one which needs a Vmu. No downloadable demo for the moment, but more details are coming in the following days.!" (02/06/2006) ==Downloads== * 3.0 - [http://archives.dcemulation.org/www.alicedreams.com/www.alicedreams.com/aliced3.zip CDI] (Zipped) * 3.0 - [http://archives.dcemulation.org/www.alicedreams.com/www.alicedreams.com/Chankast_alicedreams.zip Chankast] (Zipped) ==Official Site== *[http://archives.dcemulation.org/www.alicedreams.com/www.alicedreams.com/HomePageFR.htm Main Page] (Archived) f71eb0fa90fb67ef840097d9aefd0972564f0365 Dynamite Dreams 0 1299 2549 2023-03-02T18:07:43Z Unknown user 0 Created page with "{| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|Dynamite Dreams}}} |- border="0" cellpadding="2..." wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | {{{name|Dynamite Dreams}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:DynamitePromo1_p.png|thumb|250px|Promo Image]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.alicedreams.com/ Homepage]/<br/>[http://translate.google.com/translate?hl=en&sl=fr&u=http://www.alicedreams.com/&ei=JIBHS7ejJMvNlAeuk6wE&sa=X&oi=translate&ct=result&resnum=1&ved=0CA0Q7gEwAA&prev=/search%3Fq%3Dhttp://www.alicedreams.com/%26hl%3Den%26rls%3Dcom.microsoft:en-us Google Translated]}}} |- style="background:#ffffff" |Latest Version || {{{version|Demo 3.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|''via:'' [[Alice Dreams]]}}} |- style="background:#ffffff" |Release Date || {{{release date|11/27/2008 }}} |- style="background:#ffffff" |Author || {{{author|[[Patbier]] / [[Poche]]}}} |- style="background:#ffffff" |Type of game || {{{type|Multi-player Party}}} |- style="background:#ffffff" |Active || {{{isactive|<i>Unknown</i>}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Dynamite Dreams is a 4 player party game by the [[Alice Dreams]] developers Patbier and Poche. ===News=== From the developers: ''"For the Dream On Contest 3, we have developed a complete game starting from the mini game [[Dynamite Dreams]]. (Note: Dynamite Dreams was a bonus game in Alice Dreams v3) At the present time, the game contains 8 different maps and a challenge mode. You certainly think that you have already seen too much bombermen, and that our DC already owns an excellent one, but we didn't stop there. Our game owns unique multiplayer modes. Especially one which needs a Vmu. No downloadable demo for the moment, but more details are coming in the following days!"'' ==Links== [[Image:Youtube_32x32.png|bottom|24px|Youtube]] → [http://www.youtube.com/watch?v=kFtIxc-Ms9Y Trailer] [[Image:Youtube_32x32.png|bottom|24px|Youtube]] → [http://www.youtube.com/watch?v=5FqhsGxkckE WIP Intro] [[Image:DynamiteG4TV_p.png|24px| G4TV]] → [http://g4tv.com/videos/18706/The-Daily-Feed-with-Layla-Kayleigh-102607/ The Daily Feed with Layla Kayleigh] - 10/26/07 b735d5793d54eb0ace7aa313dd5f18092ac236ab Overclocking 0 154 2550 484 2023-03-02T18:19:26Z Unknown user 0 wikitext text/x-wiki There are two primary types of Dreamcast overclock mods. One increases speed by 10%, and the other by 20%. The 20% overclock provides greater speeds, but requires some system peripherals to be overclocked as well (for example, a VMU will not function properly and may even corrupt saves if it is not overclocked alongside the system in this scenario). ==10% Overclock== The 10% overclock is considered stable enough so that it is unnecesary to overclock accessories. See [http://dansprojects.com/dc_overclock.html this page on Dan's Projects]. ==20% Overclock== See [https://dragoncity17.wordpress.com/2021/03/17/sega-dreamcast-dc-cpu-overclock/ this page on Dragoncity] (French). e6483355361d0138c3c128f92e2253dfe24356c0 File:Scummvmmenu.png 6 1300 2551 2023-03-02T18:22:50Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Scummvmmenu}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 3493f509b7dc751b2deb26a947bf423718eefa68 File:DayofTheTentacle.png 6 1301 2552 2023-03-02T18:22:50Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=DayofTheTentacle}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1908623896af27cc297cf4d4db0eb514717fabdf File:Scummvm1.png 6 1302 2553 2023-03-02T18:22:50Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Scummvm1}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e40a330957c8055b5d41463811998cba4b78247e File:Samandmaxintro.png 6 1303 2554 2023-03-02T18:22:50Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Samandmaxintro}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e9daab051ecac15d0db1b2a7ff5c09af22b5a34a ScummVM 0 1304 2555 2023-03-02T18:23:03Z Unknown user 0 Created page with "{{Infobox_Emulator_Information| name=ScummVM| image=[[Image:scummvm1.png|280px|thumb| Broken Sword]]| homepage=[http://www.scummvm.org/ Homepage]| version=1.4.1| d..." wikitext text/x-wiki {{Infobox_Emulator_Information| name=ScummVM| image=[[Image:scummvm1.png|280px|thumb| Broken Sword]]| homepage=[http://www.scummvm.org/ Homepage]| version=1.4.1| downloads=[http://sourceforge.net/projects/scummvm/files/scummvm/1.4.1/scummvm-1.4.1-dreamcast-plainfiles.tar.bz2/download Plain Files]| release date=01/27/2012| author=Marcus Comstedt| original=[http://www.scummvm.org/ ScummVM]<br/>by ScummVM Team| systems=Classic games by<br/>LucasArts, Revolution,<br/>AdventureSoft, Coktel<br/> Vision, and more!| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=[http://dcemulation.org/1-newsdump/emulators/scummvm_0.3.0b-dreamcast_nero.zip 0.3.0b]<br/>01/06/03| best=Yes.| isactive=Yes }} ==History== '' ScummVM is a program which allows you to run certain classic graphical '' point-and-click adventure games, provided you already have their data '' files. The clever part about this: ScummVM just replaces the executables '' shipped with the game, allowing you to play them on systems for which '' they were never designed! ... '' Among the systems on which you can play those games are regular desktop '' computers (running Windows, Linux, Mac OS X, ...), game consoles '' (Dreamcast, Nintendo DS & Wii, PS2, PSP, ...), smartphones (Android, '' iPhone, PocketPC, Symbian ...), and more. [[Image:DayofTheTentacle.png|234px|Day of the Tentacle]] [[Image:scummvmmenu.png|200px|Dreamcast ScummVM menu]] [[Image:Samandmaxintro.png|234px|Sam & Max: Hit the Road]] ===Controls=== ''Controller Action '''→''' Keyboard/Mouse Action''<br/> * A '''→''' Left mouse button * B '''→''' Right mouse button * Y '''→''' Spacebar * X '''→''' 5 * X'''+'''Dpad '''→''' 1, 2, 3, 4, 6, 7, 8, 9 * Dpad '''→''' Slow mouse movement, virtual keyboard movement * Analog Stick '''→''' Fast mouse movement * L '''→''' Virtual keyboard toggle * Start '''→''' F5 ===Ini Support=== '' v1.2.0, and up. The easy way; * Place all your required files for game '' 'n' '' in it's own folder. Where '' 'n' '' is the name of the game. * Using a desktop port such as the Windows, Linux, or Mac OSX, add that game folder through the main ScummVM menu. * Exit the launcher, and locate the scummvm.ini. It is created by default in these [http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM#Using_the_configuration_file_to_configure_ScummVM locations]. * Strip down all entry lines for the game, except these three '''→''' '''''gameid''''', '''''path''''', and '''''description'''''. * Examples; [drascula] gameid=drascula description=Drascula: The Vampire Strikes Back (DOS/English) path=C:\Drascula\ [myst-win] gameid=mohawk description=Myst (Windows/English) path=C:\Myst95\ * Now change the '' 'path' '' variable to reflect the path where it'll be located on the disc. ''(ie - "path=FullThrottle" would be a sub-directory named "FullThrottle" located in the root of the cd-r structure)'' * Leave the 'cd' root off the paths. ''(ie - Do NOT use "path='''cd\'''Full Throttle")'' ===Bugs=== * 1. If you find ANY issues while playing supported games, please report the issues to the [http://sourceforge.net/tracker/?group_id=37116&atid=418820 bug-tracker]! * 2. If you do not do the above ''(ie - posting bug in the forums)'', your problem will never be officially acknowledged by the developers. ===Known limitations=== * ''Possible'' audio lag in "cdda" enabled versions of games. * ''Possible'' voice lag in the "talkie" versions of games. * Due to system requirements these games aren't compatible, or are only partially compatible. ** The Curse of Monkey Island ** The Dig ** Full Throttle ==Downloads== Stable * 1.4.1 - [http://sourceforge.net/projects/scummvm/files/scummvm/1.4.1/scummvm-1.4.1-dreamcast-plainfiles.tar.bz2/download Plain Files] - 01/27/2012 * 1.4.1 - [http://sourceforge.net/projects/scummvm/files/scummvm/1.4.1/scummvm-1.4.1-dreamcast-A-Q-nero%2Bdemos.zip/download Nero A-Q Demos] - 01/27/2012 * 1.4.1 - [http://sourceforge.net/projects/scummvm/files/scummvm/1.4.1/scummvm-1.4.1-dreamcast-R-Z-nero%2Bdemos.zip/download Nero R-Z Demos] - 01/27/2012 Nightly Builds * Buildbot - [http://buildbot.scummvm.org/snapshots/master/dc-master-latest.tar.bz2 Plain Files] ScummVM Tools ''Tools for game specific compression, extraction, etc.''<br/> * Windows - [http://sourceforge.net/projects/scummvm/files/scummvm-tools/1.4.0/scummvm-tools-1.4.0-win32.exe/download Installer], [http://sourceforge.net/projects/scummvm/files/scummvm-tools/1.4.0/scummvm-tools-1.4.0-win32.zip/download Zipfile] - 1.4.0 * Mac OS X - [http://sourceforge.net/projects/scummvm/files/scummvm-tools/1.4.0/scummvm-tools-1.4.0-macosx.dmg/download Universal binaries (10.3.9 and up)] - 1.4.0 ==Links== * [http://www.scummvm.org/ Official Site] * [http://www.scummvm.org/downloads/ ScummVM Downloads] ''(Visit for game demos & extras) 9068413ba0786a1e3db1812679b1c25287133a6c File:Bccontroller.gif 6 1305 2556 2023-03-02T18:33:36Z Unknown user 0 wikitext text/x-wiki Bccontroller 2ad47ff2c95ba3e7aeba9d757c8e8fee910ffbdf File:MEDsleeveRGB.jpg 6 1306 2557 2023-03-02T18:33:44Z Unknown user 0 wikitext text/x-wiki MEDsleeveRGB 90f68e58f838a8758eb146fcdba52858f3df5a6c Bleemcast! 0 874 2558 2028 2023-03-02T18:33:50Z Unknown user 0 wikitext text/x-wiki [[Image:bleem-rr4_psx_detail.gif|thumb|Ridge Racer on a real PlayStation]] [[Image:bleem-rr4_dc_detail.gif|thumb|Ridge Racer in bleemcast!]] [[Image:bleemcast.jpg|thumb|rgiht|bleemcast!]] bleemcast! is a commercial PlayStation 1 emulator for Dreamcast by [http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&sid=4021c15247a8129d224543722691686b&u=4493 Rand Linden] and [http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=14203 Rod Maher]. (Both were active members in the DCEmulation forum) It is not a port of the original bleem! emulator, but a completely new code base. bleemcast! improves the quality of the orginial PSX games since they run in 640x480 in bleemcast! (320x240 on a real PSX). bleem!cast was purely written in SH4 assembler. There were three official releases, each of them emulates the PlayStation 1 games they were made for: Gran Turismo 2, Tekken 3 and Metal Gear Solid. Please see the '''Offical bleemcast! FAQ''' below for more information. DCEmulation hosted a bleemcast! forum that was frequented by the bleemcast! team, who often posted information and answered users' questions. It has been closed since bleem! folded, but the forum and all of its useful information can still be viewed [http://dcemulation.org/phpBB/viewforum.php?f=25 here]. == Features == *Smooth, 640x480 3D graphics from original PlayStation-1 games (even the PS2 can't do that!) *Clean, filtered textures (you can actually READ every sign you pass at 180mph) *Full-screen anti-aliasing for added realism (no more "jaggies"!). *Save & load games to regular Dreamcast VMUs (requires dedicated VMU) *PAL Extended - no borders on PAL TVs! *Compatible with VGA boxes *Jump-Pack vibration support ==bleem!cast beta== There is a leaked beta version of bleemcast! that has made its way across the internet. This beta is capable of playing many PlayStation games although not anywhere near the same level as the commercial releases do. Many games do run but not all of them are really playable. The beta lacks saving capabilities and FMVs aren't supported, so many games whose storylines depend on FMVs or long games that require saving aren't playable at all. The authors have [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=29658 commented on the forums] about the state of the emulator's beta version and their feelings on the leak. [http://web.archive.org/web/20010515082508/http://www.bleem.com/ Bleem.com@Archive.org] http://dcemulation.org/legacy/pay-bleemcast.htm ==Official bleemcast! FAQ== This Official bleemcast! FAQ was provided by DCEmulation while bleemcast! was an actively sold product, and it is reproduced here for historical value. [[Image:MEDsleeveRGB.jpg]] '''When will bleem! for Dreamcast be released?''' The first bleem! for Dreamcast pak for Gran Turismo 2 will be available in early May 2001. How much will it cost? The MSRP is $5.95. Where can I buy bleem! for Dreamcast? bleem! should be available at most major game and consumer electronics retailers, as well as at a number of online sites. EBWorld will be carrying the product at retail and online. '''You previously announced that bleem! for Dreamcast would be in 100-game paks, now you are launching individual titles, what's the deal?''' When we originally announced bleem! for Dreamcast, we expected that the remaining changes to the core code would bring most titles up to near full compatibility, with only minor tweaking to attain full compatibility. After months of working on the software and extensive individual game testing, we realized that there was not a single fix across the board sufficient to bring the final product to a level that console gamers demand -- While PC gamers are used to dealing with compatibility issues and configuration settings, console gamers expect absolute perfection without any hassles right from the moment they hit the start button. While the core bleem! for Dreamcast emulator already ran many titles well enough to be playable, the overriding goal of "glitch-free" emulation meant that any remaining issues would still need to be addressed before release. The nature of bleem!'s operation, and the differences from typical lower-level system-simulator style emulators, meant that individual code "tweaks" would need to be written and adjusted for each individual title to handle any peculiarities or unusual techniques used by the particular game. The result is hundreds of hours of work towards getting each individual title fully compatible, whether it is a popular bestseller such as Gran Turismo 2, or an obscure unpopular title that most people wouldn't want to play on their Dreamcast. We also received a lot of feedback from users unhappy with the proposed $19.95, 100-game paks. Most users weren't thrilled that there were really only 5-8 titles they that wanted to play on their Dreamcast, and they would potentially need to buy all four paks just to get all of the titles they wanted. It could potentially cost a user $80 just to play a handful of titles with bleemcast!. The obvious conclusion was to change our focus from trying to get absolutely every game working with all the bleem!-enhancements, to getting those games that mattered most at a much higher level of enhancement than we originally planned - This change in direction means that the entire bleem! core could now be adjusted, tweaked and changed without any impact on any other titles. The results, although far later than we had hoped for, are well worth it as each bleem! for Dreamcast pak results in an experience that's far closer to a typical "port" than we expected could be achieved with our original designs. To complete the experience, we added all the "bells and whistles" that gamers expect to see in a native Dreamcast title, such as VGA box support and compatibility with a huge range of controllers and peripherals including vibration packs, steering wheels and our own bleempod! for using native PlayStation peripherals on your Dreamcast! Finally, since bleem! for Dreamcast supports all international regions of software automatically, we added full PAL-extended support (to remove those ugly NTSC borders) and PAL60Hz support that automatically activates when playing NTSC game software on a PAL Dreamcast! Releasing single game versions of bleemcast! will also allow us to concentrate our resources on the titles gamers really want to play, at prices that make owning each bleemcast! version very attractive. We would also be able to support newer titles closer to their release dates should demand warrant bringing a particular new release to the Dreamcast, and we can focus on best selling and platinum titles that deserve to be played with bleem! enhancement. '''What titles do you plan to release as bleem! for Dreamcast paks?''' We are looking at a number of potential titles to begin with, however we are not announcing any at this time. I pre-ordered the 100 game pak, but now the product is different. '''How do I cancel my pre-order, or change it to receive the GT2 version?''' You need to contact the retailer who holds your pre-order reservation for specific details on how they handle pre-order cancellations. '''What is the next title?''' We have narrowed our list down to a handful of very popular titles and will make an announcement when the coding is finished on future titles. When will the next title come out? There is no expected release date at this time. '''How does bleem! for Dreamcast work?''' You insert the bleem! for Dreamcast disc into your Dreamcast console and close the lid. bleem! loads into local memory and then prompts you to insert the appropriate PSX disc. You swap discs, close the lid and press the start button. '''Does bleem! for Dreamcast work with VMUs?''' Yes, you will be able to save your bleem! games on a new or freshly formatted VMU. '''Can I store Dreamcast saved games and PlayStation saved games on the same VMU?''' No, due to different file management structures, you can't save both types of saved games on the same VMU. '''When will the bleempod! and bleempad! be released?''' With Sega discontinuing Dreamcast manufacturing, we are re-evaluating whether or not demand is high enough to produce the pod and pad. '''Is it possible to play back-ups of PSX games with bleem! for Dreamcast?''' We can't prevent it since the technology that verifies that a disc is an original PSX title is patented by Sony and if we used it, we would be in violation of that. '''Will I be able to play PAL games?''' Yes. '''Will I be able to play NTSC games with a PAL Dreamcast?''' Yes. '''Will bleemcast! work with the VGA-box?''' Yes. == Saving FAQ == '''bleemcast! requires it's own, dedicated vmu for saving games.''' Yeah, it kind of sucks, but the two kinds of storage devices are just too different. PlayStation games are written to work with PSX memcards, and they just sort of slap the save data right into various memory addresses. VMUs use FAT tables and different methods of accessing and saving data, and PSX game saves don't happily coexist on a VMU with DC data. Besides which, even though the VMU has the same capacity as a memcard, the directory structure on a VMU doesn't leave enough room for a full 15 blocks of PSX data. We're still working on it, and may figure out a way around it for future paks. or there's always the bleempod... '''you'll need to format the VMU before you can use it.''' Your VMU is already set up for Dreamcast games - in order for it to work with bleem! and PSX games, it needs to be formatted like a PSX memcard. So DON'T format the VMU from the Sega boot screens, and DO format it from within the game. The first time you try to save to a non-bleem! formatted VMU, the game will ask you if you want to "initialize" or "format" the "memcard". '''NOTE: formatting a VMU for use with bleem! ERASES any game saves on the VMU! Make sure you know what you're erasing!''' If you're cool with erasing the VMU, tell the game to go ahead and it'll do the rest for you. After you've formatted the VMU for PSX games, it will only work with bleem!ed games. If you want to use it wil Dreamcast games again, you'll have to use the options the Dreamcast boot menu to wipe the VMU and format it back to DC. '''bleem! uses Dreamcast controller ports A and B.''' The PlayStation has two sets of inputs on the front of the console, and each will accept one controller and one memory card. So when the PSX game talks about "Controller Port 2" or "Memory Card Slot 1", this is what it means in bleem!: [[Image:bccontroller.gif]] 28d0090db1b71250238181abc9512f10d609454e MediaWiki:Liberachat-url 8 1307 2559 2023-03-02T19:12:02Z Unknown user 0 Created page with "https://web.libera.chat/?nick=DCChatter?##dreamcast" wikitext text/x-wiki https://web.libera.chat/?nick=DCChatter?##dreamcast 30da71832aa5f03ad5993d427df63169c15702fe MediaWiki:Sidebar 8 10 2560 1973 2023-03-02T19:12:09Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|Dreamcast Wiki Home ** forums-url|DCEmu Forums ** liberachat-url|##dreamcast IRC ** simulant-discord-url|Simulant Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair ** Emulators on Dreamcast|Emulators * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES b54764d1bfacf03f6633ab2b2c7a77b618c5deb0 2561 2560 2023-03-02T19:13:10Z Unknown user 0 wikitext text/x-wiki * navigation ** mainpage|dreamcast.wiki Home ** forums-url|DCEmu Forums ** liberachat-url|##dreamcast IRC ** simulant-discord-url|Simulant Discord * Sections ** DCWiki:Software|Software ** DCWiki:Hardware|Hardware ** Development|Development ** Repair|Repair * Wiki ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * SEARCH * TOOLBOX * LANGUAGES afb8956a3c64749f633717e787d67cfb797fb718 VMU development 0 99 2562 2326 2023-03-02T19:44:08Z Unknown user 0 /* DC Anim */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual ef97b89f0cef7aa385732d7586745d6e6da9d498 2563 2562 2023-03-02T19:47:39Z Unknown user 0 /* Hardware */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 9cafce0bb006012d199f032cbccbbc879c43e285 2564 2563 2023-03-02T19:48:59Z Unknown user 0 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual e93085ce0b02d59b8159fa77ec6279c73c6c7e45 Getting Started with Dreamcast development 0 694 2565 1915 2023-03-02T23:02:06Z Unknown user 0 /* Cloning the KOS git repository */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. f551602ce67d8a45d48af6a7441b7b120552b705 2566 2565 2023-03-02T23:02:30Z Unknown user 0 /* Building kos-ports */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 12.2.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 12.2):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 8404c120cc969efeadd65199503eb9b065f7c72a List of Maple devices 0 1308 2567 2023-03-03T00:31:32Z Unknown user 0 Created page with "The purpose of this article is to archive and sort all the information gathered on maple devices using Quzar's MapleTest. {| border="1" cellpadding="2" class="wikitable sorta..." wikitext text/x-wiki The purpose of this article is to archive and sort all the information gathered on maple devices using Quzar's MapleTest. {| border="1" cellpadding="2" class="wikitable sortable" style="width:100%; font-size:95%;" !width="28%"|Plain Name !width="20%"|Product Name !width="8%"|Product License (if not Sega) !width="8%"|Region Code !width="8%"|Connection !width="12%"|Standby Current consumption !width="12%"|Maximum Current consumption !width="16%"|Functions !width="20%"|Extra info !width="8%"|Bytes Returned (reported) !width="20%"|Notes |- !colspan=11 | Official (First and Second Party) |- |Sega Official VMU (US Green or White) |[[Visual Memory]] | ~ |ff |00 |007c |0082 |0e000000, 403f7e7e, 00100500, 00410f00 |Version 1.005,1999/10/26,315-6208-05,SEGA Visual Memory System BIOS Produced by IOS Producedem Bem Bem Bem B |192 |Official NTSC-U VMU, Transparent Green or Plain White. |- |Sega Official VMU (US White) |[[Visual Memory]] | ~ |ff |00 |007c |0082 |0e000000, 403f7e7e, 00100500, 00410f00 |Version 1.005,1999/04/15,315-6208-03,SEGA Visual Memory System BIOS Produced by IOS Producedem Bem Bem Bem B |192 |Official NTSC-U VMU, Standard White. |- |Sega Official VMU (US White) |[[Visual Memory]] | ~ |ff |00 |007c |0082 |0e000000, 403f7e7e, 00100500, 00410f00 |Version 1.005,1999/04/28,315-6124-07,SEGA Visual Memory System BIOS Produced by IOS Producedem Bem Bem Bem B |192 |Official NTSC-U VMU, Standard White. |- |Sega Official Controller (US) |[[Dreamcast Controller]] | ~ |ff |00 |01ae |01f4 |01000000, fe060f00, 0, 0 |Version 1.010,1998/09/28,315-6211-AB ,Analog Module : The 4th Edition.5/8 +DFodulodulodulodulodulodulodul |192 |Official NTSC-U Controller, standard white. |- |Sega Official Controller (US) |[[Dreamcast Controller]] | ~ |ff |00 |01ae |01f4 |01000000, fe060f00, 0, 0 |Version 1.100,1999/08/05,315-6275 ,Analog Module : The 4th Edition.5/8 ,AD1odulodulodulodulodulodulodul |192 |Official NTSC-U Controller, Sega Sports and probably others. |- |Sega Official Mouse (US) |[[Dreamcast Mouse]] | ~ |ff |00 |0190 |01f4 |00020000, 00070002, 0, 0 |Version 1.000,2000/02/25,315-6211-AT ,3 Button & X-Y Ball & Z Wheel ,400dpi & X & X & X & X & X & X & X |192 |Should be the same for all mice as it's not region locked. |- |Sega Official Keyboard (US) |[[Keyboard]] | ~ |01 |00 |012c |0190 |40000000, 80000502, 0, 0 |Version 1.010,1999/04/27,315-6211-AM ,Key Scan Module : The 2nd Edition. 04/25 Mod Mod Mod Mod Mod Mod Mod |192 |Standard US Keyboard (maybe the SegaNet one is different?) |- |pop'n music controller (Official) |[[pop'n music controller]] | ~ |ff |00 |00aa |012c |01000000, ff060000, 0, 0 |Version 1.000,1998/10/29,315-6125-AK ,Da,Ua,Ra,La,A,B,C,X,Y,Start Button ,La,,La,,La,,La,,La,,La,,La, |192 |Offical Konami pop'n music controller (RU 015) |- |Sega Official Microphone (US - Seaman) |[[SoundInputPeripheral (S.I.P.)]] | ~ |03 |01 |012c |012c |10000000, 0f000000, 0, 0 |Version 1.000,1998/05/22,315-6182 S4(SegaSoundSamplingSystem)/SamplingRate11.0257or8.085kHz/Bit14or8bit/NTSC only/Consumer Deveropment & Mamufacturing DIV.CSPD2-3 |284 |Not sure if this is identical to other bundled mics. |- |Dreameye Mic |[[MicDevice for Dreameye]] | ~ |0f |01 |012c |012c |10000000, 3f000000, 0, 0 |Version 1.000,2000/02/24,315-6182A S41(SegaSoundSamplingSystem)/SamplingRate10.9090or8.000kHz/Bit14or8bit/NTSC/PAL/Consumer Deveropment & Mamufacturing DIV.CSRD |284 |Mic that comes with the DreamEye. hehe 'deveropment & mamufacturing' |- |Dreameye |[[Dreamcast Camera Flash Device]] | ~ |ff |00 |07d0 |0960 |01000000, 00080000, 0, 0 |Version 1.000,2000/02/25,315-6283 1.00 |152 |Dreameye Camera. Identifies as 6 maple devices, this is the first. |- |Dreameye |[[Dreamcast Camera Flash LDevice]] | ~ |ff |00 |0000 |0000 |00080000, 30a800c0, 0, 0 |Version 1.000,2000/02/25,315-6283 1.00 |152 |Dreameye Camera. Identifies as 6 maple devices, all but the first return this. |- !colspan=11 | Third Party |- |ASCII brand controller w/rumble |[[ASCII STICK]] | ~ |ff |00 |010e |0172 |01000000, ff070000, 0, 0 |Version 1.000,1998/06/09,315-6125-AC ,Direction Key & A,B,C,X,Y,Z,Start Buttonn Ken Ken Ken Ken Ken Ken Ke |192 |ASCII Pad's Controller device. The built in rumble appears on *2. *1 is a slot for a regular device. |- |ASCII brand controller w/rumble |[[Puru Puru Pack]] | ~ |ff |00 |00c8 |0640 |00010000, 00000101, 0, 0 |Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 n Mon Mon Mon Mon Mon Mon Mo |192 |ASCII Pad's Rumble device. The built in rumble appears on *2. *1 is a slot for a regular device. It seems that they identically duplicated an official puru's response. |- |Madcatz Keyboard Adapter |[[Dreamcast Keyboard]] | ~ |ff |00 |015e |01f4 |40000000, 80070502, 0, 0 |Version 1.000,1999/09/29,Mad Catz Inc. 1.00 |152 |Adapter that has PS/2 and AT ports |- |Performance Tremor Pack |[[Puru Puru Pack]] | ~ |ff |00 |00c8 |0640 |00010000, 00000101, 0, 0 |Version 1.000,1998/11/10,315-6211-AH ,Vibration Motor:1 , Fm:4 - 30Hz ,Pow:7 n Mon Mon Mon Mon Mon Mon Mo |192 |3rd party rumble 'Performance' make. |- |Performance Memory Card |[[Visual Memory]] | ~ |ff |00 |007c |0082 |0e000000, 00410f00, 00100500, 00410f00 |V312 ver 1.0 1/June/99 |136 |Performance brand Memory Card. Same info from regular and 4x (showing they're identical). |- |} 00f8d7be07403d47fef526f0ed026a6568aaccd2 File:Null Terminator Inside 2.jpg 6 1309 2568 2023-03-03T00:37:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Null Terminator Inside 2}} |date=2008-03-17 04:08:06 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0fe21fac359cf14cac9bc6bb83d6ce830e05a5c8 File:Null Terminator Outside.jpg 6 1310 2569 2023-03-03T00:37:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Null Terminator Outside}} |date=2008-03-17 04:05:17 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d5cf4c0559cea401d7e18d22f8929ba122659100 File:Null Terminator With Casing.jpg 6 1311 2570 2023-03-03T00:37:46Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Null Terminator With Casing}} |date=2008-03-17 04:12:22 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b37c8e938cee2d45e620f77bfea4af1c8253b6ff G2 Terminator 0 1312 2571 2023-03-03T00:38:21Z Unknown user 0 Created page with "[[File:Null Terminator Inside 2.jpg|thumb|Null Terminator Inside 2]] [[File:Null Terminator Outside.jpg|thumb|Null Terminator Outside]] File:Null Terminator With Casing.jpg|..." wikitext text/x-wiki [[File:Null Terminator Inside 2.jpg|thumb|Null Terminator Inside 2]] [[File:Null Terminator Outside.jpg|thumb|Null Terminator Outside]] [[File:Null Terminator With Casing.jpg|thumb|Null Terminator With Casing]] The G2 Terminator is a device that connects to the Dreamcast's external expansion port and terminates the G2 bus. It has no other function. This device was included on some Dreamcast consoles that did not ship with modems, such as in Hong Kong. 0b932c31750cbae1ffdbb6b507aab3114066e7c2 2572 2571 2023-03-03T00:41:04Z Unknown user 0 wikitext text/x-wiki [[File:Null Terminator Inside 2.jpg|thumb|Null Terminator Inside 2]] [[File:Null Terminator Outside.jpg|thumb|Null Terminator Outside]] [[File:Null Terminator With Casing.jpg|thumb|Null Terminator With Casing]] The G2 Terminator is a device that connects to the Dreamcast's external expansion port and terminates the G2 bus. It has no other function. This device was included on some Dreamcast consoles that did not ship with modems, such as in Hong Kong. It is not the same as the G2 dummy adapter, which was also included on Dreamcast consoles without modems, like kiosk models. The dummy adapters are entirely plastic, including the connector, with no circuitry to terminate the bus. 4afd4d93d0b92ea1b8d8c45d788da7e72214eea1 2573 2572 2023-03-03T00:41:21Z Unknown user 0 wikitext text/x-wiki [[File:Null Terminator Inside 2.jpg|thumb|Null Terminator Inside 2]] [[File:Null Terminator Outside.jpg|thumb|Null Terminator Outside]] [[File:Null Terminator With Casing.jpg|thumb|Null Terminator With Casing]] The G2 Terminator is a device that connects to the Dreamcast's external expansion port and terminates the G2 bus. It has no other function. This device was included on some Dreamcast consoles that did not ship with modems, such as in Hong Kong. It is not the same as the G2 dummy adapter, which was also included on Dreamcast consoles without modems, like kiosk models. The dummy adapters are entirely plastic, including the connector, with no circuitry to terminate the bus. 034c8a4ca06209b280f648c67847708cb91b69bd 2575 2573 2023-03-03T00:43:25Z Unknown user 0 wikitext text/x-wiki [[File:Null Terminator Inside 2.jpg|thumb|Null Terminator Inside 2]] [[File:Null Terminator Outside.jpg|thumb|Null Terminator Outside]] [[File:Null Terminator With Casing.jpg|thumb|Null Terminator With Casing]] The G2 Terminator is a device that connects to the Dreamcast's external expansion port and terminates the G2 bus. It has no other function. This device was included on some Dreamcast consoles that did not ship with modems, such as in Hong Kong. It is not the same as the G2 dummy adapter, which was also included on Dreamcast consoles without modems, like kiosk models. The dummy adapters are entirely plastic, including the connector, with no circuitry to terminate the bus. A discussion can be found on [https://dcemulation.org/phpBB/viewtopic.php?f=31&t=97158 our forums here]. 4241dc15e7b3a0d55da03e7814bd4d5c8f94bb10 DCWiki:Hardware 4 82 2574 1836 2023-03-03T00:42:29Z Unknown user 0 /* Hardware */ wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]], [[G2 Terminator|Terminator]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCDigital]] HDMI, [[S/PDIF]], [[Internal VGA]], [[MIDI expansion|MIDI]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]], [[32MB RAM expansion]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} 1f6f33d2af52a264fa04f7fbf6a6cc438ddaccaf Fast Striker 0 1313 2576 2023-03-03T00:44:44Z Unknown user 0 Created page with "[[NGDEVTEAM]]'s FAST STRIKER is a 2D arcade shooting game with emphasis on scoring. You can choose between 3 game modes with different scoring systems. This game features six..." wikitext text/x-wiki [[NGDEVTEAM]]'s FAST STRIKER is a 2D arcade shooting game with emphasis on scoring. You can choose between 3 game modes with different scoring systems. This game features six stages of excellent 2D arcade game play with over 40 unique enemy types, super smooth 3D scrolling backgrounds, huge CGI bosses and it features the biggest Megabit count ever since the beginning of NEO·GEO games. [[Image:Fast Striker Box Arts.jpg]] == Trailer == * [http://www.youtube.com/watch?v=Kr96liMQIis FAST STRIKER trailer at Youtube] == Features == *6 Stages *3 Game Modes: Original/Maniac/Novice *Elaborate Scoring System *Up to 180 Enemy Bullets Simultaneously on Screen *40+ Fully Animated CGI Enemies *6+ Huge Fully Animated Boss Enemies *3D Scrolling CGI Backgrounds *Constant 60 fps *Difficulty Rank System *Internet Ranking via Code *Supports VMU, Rumble Pack, Standard Controller & Arcade Stick (buttons are fully customizable) *Compatible with NTSC and PAL-60, S-Video & RGB at 240p, VGA at 480p *REGION FREE d08fc25e4a15a45d4128d1b595fa77703098d1ac 2577 2576 2023-03-03T00:45:15Z Unknown user 0 wikitext text/x-wiki [[NG:Dev.Team]]'s FAST STRIKER is a 2D arcade shooting game with emphasis on scoring. You can choose between 3 game modes with different scoring systems. This game features six stages of excellent 2D arcade game play with over 40 unique enemy types, super smooth 3D scrolling backgrounds, huge CGI bosses and it features the biggest Megabit count ever since the beginning of NEO·GEO games. [[Image:Fast Striker Box Arts.jpg]] == Trailer == * [http://www.youtube.com/watch?v=Kr96liMQIis FAST STRIKER trailer at Youtube] == Features == *6 Stages *3 Game Modes: Original/Maniac/Novice *Elaborate Scoring System *Up to 180 Enemy Bullets Simultaneously on Screen *40+ Fully Animated CGI Enemies *6+ Huge Fully Animated Boss Enemies *3D Scrolling CGI Backgrounds *Constant 60 fps *Difficulty Rank System *Internet Ranking via Code *Supports VMU, Rumble Pack, Standard Controller & Arcade Stick (buttons are fully customizable) *Compatible with NTSC and PAL-60, S-Video & RGB at 240p, VGA at 480p *REGION FREE a86b2f4ae714c9934df0fc2a32bf4fa94b029f76 OpenBORManual 0 1314 2578 2023-03-03T00:46:20Z Unknown user 0 Created page with "OpenBoR Guide by Fugue & Bloodbane. Updated by O Ilusionista. '''Last update on 2019.09.01 - by O Ilusionista''' *~ Added more info about DUCK *~ Added DUCKING, DUCKRISE, EDG..." wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Updated by O Ilusionista. '''Last update on 2019.09.01 - by O Ilusionista''' *~ Added more info about DUCK *~ Added DUCKING, DUCKRISE, EDGE, BACKEDGE, LOSE, VICTORY =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== *~You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. *~Put this program in same folder with .pak that you want to 'explode'. *~Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). *~If you do it right, a window showing DOS messages about extracting files will appear. *~The extracted files should be in same folder in new folder named DATA. *~NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== *~Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). *~If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. *~No matter which engine you're using, you can play the mod by running the .exe. *~NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== *~You'll need a program called PACKER.exe. *~Put this program in same folder with DATA folder which contains your mod. *~Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. *~If you do it right, a window showing DOS messages about packing files will appear. *~The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== ajspecial (bi) *~Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. *~If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. autoland {int} *~{int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. nocost {bi} *~Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something nolost {bi} *~Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. noaircancel {int} *~Sets whether players can cancel their jumpattack with other jumpattacks or not. *~In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all combodelay {int} *~This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. *~Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo *~Great to disable cheap infinite combo! offscreen_noatk_factor {bi} *~This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== blockratio {bi} *~If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead mpblock {bi} *~If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. *~blockratio needs to be set before using this. nochipdeath {bi} *~If this is set, entities can't die by blockdamage (damage from blocking). *~blockratio needs to be set before using this. *~Entities health can be reduced to 1 health with this the next successful blocks won't take any health. blockback {bi} *~Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== colourselect {bi} {bi} *~{bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. *~If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. *~That's "colour" with a u, not "color". Some countries spell it different ways. spdirection {b1} {b2} {b3} {b4} *~Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. *~{b1} is for player 1, {b2} is for player 2 and so on. *~Default is 1 0 1 0. ==Miscellaneous== nodropen *~Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). *~This command doesn't take any argument. Declaring it is enough to set it. forcemode {bi} *~Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. versusdamage {bi} *~Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. nocheats {bi} *~Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden *~Those who like fair play should use this ;). nodropspawn {bi} *~When it is on, the spawn position will be restricted to spawn entry setting. nodebug {bi} *~in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type. For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. No need to change the others if you aren't using more animations than the max value. maxattacks {max} *~Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. *~{max} is number of available animations. *~Default is 4. maxattacktypes {max} *~Sets the maximum number of attack types. *~PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. *~{max} is number of available types. *~Default is 10 & maximum value is 99. maxfollows {max} *~Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. *~{max} is number of available animations. *~Default is 4. maxfreespecials {max} *~Sets the maximum number of free specials. *~{max} is number of available free specials. *~Default is 8. maxidles {max} *~Sets the maximum number of IDLEs. *~{max} is number of available IDLEs. *~Default is 1. maxwalks {max} *~Sets the maximum number of WALKs. *~{max} is number of available WALKs. *~Default is 1. maxbackwalks {max} *~Sets the maximum number of BACKWALKs. *~{max} is number of available BACKWALKs. *~Default is 1. maxups {max} *~Sets the maximum number of UPs. *~{max} is number of available UPs. *~Default is 1. maxdowns {max} *~Sets the maximum number of DOWNs. *~{max} is number of available DOWNs. *~Default is 1. ==Bonus== lifescore {int} *~Determines how many score points players must earn to get one life or 1Up. *~Default value is 50000. *~Set this to big value to prevent players from getting life from points. *~DO NOT set this to 0 otherwise you'll get crash when hitting enemy. credscore {int} *~Determines how many score points players must earn to get one credit or continue. *~Default value is unknown. But by default players won't get credit from score. *~Set this to big value to prevent players from getting credit from points. *~DO NOT set this to 0 otherwise you'll get crash when hitting enemy. nomaxrushreset {int} *~Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== *~These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. *~Each command loads one entity so that means you have to declare these commands more than once to load many entities. *~Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. *~load {name} {path} **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. *~know {name} {path} **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. *~You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 8 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> *~Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) *~Make sure the optional fonts are available before using them! PS: Not all symbols are necessary.You can add which you need. * NUMBERS must be included in font images or openbor will crash without error. * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== hiscorebg {bi} *~If set to 1, the high score screen will have a background. Normally, it's just text on black. completebg {bi} *~Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. *~The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. showcomplete {x1} {y1} {x2} {y2} {x3} {y3} *~Determines the position of "STAGE # COMPLETE". *~{x1} and {y1} determines "STAGE"'s position. *~{x2} and {y2} determines the number's position. This number shows the completed stage's number. *~{x3} and {y3} determines "COMPLETE"'s position. *~ x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} *~Determines the position of "Clear Bonus" and its scores for each player. *~{x0} and {y0} determines "Clear Bonus"' position. *~{x1} and {y1} determines Player 1's score bonus' position. *~{x2} and {y2} determines Player 2's score bonus' position. *~{x3} and {y3} determines Player 3's score bonus' position. *~{x4} and {y4} determines Player 4's score bonus' position. *~ x and y work exactly like they are for 'showcomplete'. *~The score will only be shown if the respective player is present when stage completes though. lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} *~Determines the position of "Lives Bonus" and its scores for each player. *~{x0} and {y0} determines "Lives Bonus"' position. *~{x1} {y1} {x2} {y} {x3} {y3} {x4} {y4} works exactly like for 'clearbonus' except that they are for life bonus. totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} *~Determines the position of "Total Score" and its scores for each player. *~{x0} and {y0} determines "Total Score"'s position. *~{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} works exactly like for 'clearbonus' except that they are for Total Score. showrushbonus {int} *~Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted *~Make sure you have set 'rush' above before setting this. rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} *~Determines the position of "Rush Bonus" and its scores for each player. *~{x0} and {y0} determines "Rush Bonus"' position. *~{x1} {y1} {x2} {y} {x3} {y3} {x4} {y4} works exactly like for 'clearbonus' except that they are for rush bonus. scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type} *~Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. *~{stage bonus} is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 *~{life bonus} is life's bonus (lives * life bonus). Defaults to 1000 *~{rush bonus} is max rush bonus (max rush * rush bonus). Defaults to 100 *~{bonus type} determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. *~NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause} *~write "pauseoffset" in levels.txt to change fonts and offset of pause strings. *~{font0} is font index for "continue"/"end game" strings. default 0 *~{font1} is font index for "continue"/"end game" highlighted strings. default 1 *~{xpos} is x position for "continue"/"end game" strings *~{ypos} is y position for "continue"/"end game" strings *~{font_pause} is font index for "PAUSE" string. default 3 *~{xpos_pause} is x position for "PAUSE" string *~{ypos_pause} is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] p{#}life {x} {y} *~Determines the position of player's life bar. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. p{#}icon {x} {y} *~Determines the position of player's icon. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. p{#}mp {x} {y} *~Determines the position of player's MP bar, if player has MP that is. *~Works exactly like p{#}life, except it affects player's MP bar instead. p{#}lifex {x} {y} {font} *~Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. *~{#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". *~{font} determines which font is used for the "x". *~Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) *~Make sure the optional fonts are available before using them! p{#}lifen {x} {y} {font} *~Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~ {x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. *~ {font} determines which font is used for the number. *~ Font reference is the same as 'p{#}lifex' above. *~ Default value is 3 or font4.gif. p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font} *~Determines the position of player's status. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x1} and {y1} determines player's name position. *~{x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. *~{x3} and {y3} determines player's score position. *~ x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. *~{font} determines which font is used for the texts. *~Font reference is the same as 'p{#}lifex' above. *~Default value is 0 or font.gif. p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font} *~Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. *~{x1} and {y1} determines player's name position. *~{x2} and {y2} determines "Select Hero"'s position. *~{x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. *~{font} determines which font is used for the texts. *~Font reference is the same as 'p{#}lifex' above. *~Default value is 0 or font.gif. p{#}shoot {x} {y} {font} *~Determines the position of weapon's counter when shootnum is used. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. *~{font} determines which font is used for the texts. *~Font reference is the same as 'p{#}lifex' above. *~Default value is 0 or font.gif. mp{#}icon {x} {y} *~Determines the position of magicbar's icon. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. p{#}iconw {x} {y} *~Determines the position of player's icon for players with weapon. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. e{#}life {x} {y} *~Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. e{#}icon {x} {y} *~Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. e{#}name {x} {y} {font} *~Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. *~{font} determines which font is used for the texts. *~Font reference is the same as 'p{#}lifex' above. *~Default value is 0 or font.gif. p{#}smenu {x1} {y1} {x2} {y2} *~Determines the position of players in select screen. *~ {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x1} and {y1} determines player's position. *~{x2} and {y2} determines player's "Ready!" position. *~ x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png lbarsize {w} {h} {noborder} {type} {orientation} {border} {shadow} {graph} {backfill} *~Controls the size of lifebars. *~This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *~{w} is the maximum amount of health the bar can display. Defaults to 100. *~{h} is the height of the lifebar in pixels. Defaults to 5. *~{noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. *~ {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. *~{orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. *~{border} sets layer adjustment of outer border. Default to 0. *~{shadow} sets layer adjustment of border shadow. Default to 0. *~{graph} sets layer adjustment of graph fill. Default to 0. *~{backfill} sets layer adjustment graph background. Default to 0. *~The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. mpbarsize {w} {h} {noborder} {type} {orientation} {border} {shadow} {graph} {backfill} *~Controls the size of mpbars. *~Works exactly like 'lbarsize'. olbarsize {w} {h} {noborder} {type} {orientation} {border} {shadow} {graph} {backfill} *~Controls opponent's lifebars size. If not available, 'lbarsize' will be used. *~Works exactly like 'lbarsize'. rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4} *~This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. *~As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. *~{flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. *~ {duration} sets how long the counter will be on before it expires. *~ {text1} sets what text to be displayed for hits counter. *~ {f1} sets which font to be used for {text1}. *~ {f2} sets which font to be used for hits counter's number. *~ {text2} sets what text to be displayed for maximum hits. *~ {f3} sets which font to be used for {text2}. *~ {f4} sets which font to be used for maximum hit' number. *~ Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) *~Make sure the optional fonts are available before using them! *~Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} *~Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. *~{#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *~{x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. *~{x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. *~{x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. *~{x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. *~x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. timeloc {x} {y} {w} {h} {noborder} *~Controls the position of the clock timer. *~To change the font, you'll need to work with the font file, not this command. *~{x} and {y} control how far right and down (respectively) the timer is from the top left of the screen. *~{w} and {h} control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. *~{noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. *~The default values are 149, 4, 21, 20, and 0, respectively. timeicon {path} {x} {y} *~Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). *~{path} is the location relative to OpenBoR of the icon's .gif. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. bgicon {path} {x} {y} *~Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). *~{path} is the location relative to OpenBoR of the icon's .gif. *~{x} and {y} are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. scoreformat {flag} *~{flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== noslowfx {bi} *~If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. custfade {int} *~{int} determines how long it takes for music to fade out. musicoverlap {bi} *~Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. noslow {bi} *~Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== maxplayers {int} *~Determines how many players could play at same time. *~{int} could be 1, 2, 3 or 4. *~This setting can be overriden by same command in level sets (see below). loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf} *~This command allows custom loading background to be displayed while models are being loaded. *~The background must be named loading.gif and placed under data/bgs/ folder. *~{set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. *~{bx} and {by} determines x and y coordinates of loading bar top left's location respectively. *~{bsize} determines loading bar's length. *~{tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. *~{tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf} *~This command allows custom loading background to be displayed while levels are being loaded. *~The background must be named loading2.gif and placed under data/bgs/ folder. *~The other variables have same effect with 'loadingbg'. itemtrans {bi} *~This makes dropped items transparent. Make sure the items have transparency set before setting this. equalairpause {bi} *~Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== set {name} *~Marks the start of a difficulty level or game mode. *~{name} is the name of the difficulty which will be selectable from the difficulty select menu. typemp {int} *~Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. cansave {int} *~Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. skipselect {name} {name} {name} {name} *~This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. *~{name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. *~MAKE SURE the defined player are loaded before using this! *~You can empty all values to skip default select screen. However don't forget to set select screen text right after it. *~You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> nosame {b1} {b2} *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. *~{b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. *~{b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> noshare {bi} *~Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. lives {int} *~The player will start with {int} lives. credits {int} *~Players will start with {int} credits. *~If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. ifcomplete {int} *~Can be used to create 'locked' levels if {int} is set to 1 or higher. *~In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. *~OpenBoR will save player's progress so no need to do it all at once. *~They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. *~Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. maxplayers {int} *~Determines how many players could play at same time just for current level set. *~{int} could be 1, 2, 3 or 4. *~This setting overrides same command in general settings (see above). continuescore {int} *~Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. disablegameover {int} *~set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display disablehof {int} *~set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display noshowcomplete {int} *~set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== z {zmin} {zmax} {BGheight} *~Changes the location of stage boundaries. *~{xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. *~{xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. *~{BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. *~This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. *~You can spawn entities outside of this range, but once they enter the playing field they can't escape again. file {path} *~This command is for setting levels to play in a 'set'. *~{path} is the location of a .txt file which describes a level. *~Since this command only sets one level, you may need to declare more of this to set the other levels. *~If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). *~Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. scene {path} *~This command is for setting cutscenes to play in a 'set'. *~{path} is the location of a .txt file which describes a cutscene. *~Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. *~If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). *~Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. select {path} *~This command is for setting select screen files to play in a 'set'. *~{path} is the location of a .txt file which sets custom select screen. *~This can be declared more than once in same game mode and playing order is from the 1st one to last one. *~Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. next *~This command doesn't need any arguments. *~When this command is reached, the Stage Complete scene will play, and Scores will be tallied. branch {name} *~Used to give name to warp destination for endlevel entities which uses 'branch'. *~{name} is the name of the destination. *~Used together with 'branch' feature (see below). end *~When this is reached, the game will end regardless of the levels after it. *~There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. blackbox {R} {G} {B} *~Determines the color of the 'shadow' around the lifebar and the bar at 500 health. whitebox {R} {G} {B} *~Determines the color of the outline around the lifebar and the bar at 600 health and up. color{#} {R} {G} {B} *~Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. *~There's no space between "color" and {#} in color{#}. *~{#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. *~color500 is also used as the background of the lifebar, and is displayed with transparency. *~If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. colormagic {R} {G} {B} *~Controls the color of the MP bar. colormagic2 {R} {G} {B} *~When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. shadowcolor {R} {G} {B} *~Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. colourdepth {int}bit *~DEPRECIATED. All modules are displayed with a 32bit color screen. *~This command is for activating true color mode. *~Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. *~It's 'colour' not 'color'. colourdepth {int}bit ~ DEPRECIATED. All modules are displayed with a 32bit color screen ~This command is for activating true color mode. ~Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. ~It's 'colour' not 'color'. video {int} *~This command determines what video modes used by this mod. *~If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. *~Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 *~This command can't be overriden in OpenBoR menu. scenes {path} *~This command is used to define alternate path for widescreen scenes. *~{path} points to folder containing those scenes. Note: defined path must end with slash (/). backgrounds {path} *~This command is used to define alternate path for widescreen backgrounds. *~{path} points to folder containing those backgrounds. Note: defined path must end with slash (/). levels {file} *~This command is used to define alternate file for alternate levels.txt. *~{file} points to that file. The pointed file must be placed in directy under DATA folder like default levels.txt. *~The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. models {file} *~This command is used to define alternate file for alternate models.txt. *~{file} points to that file. The pointed file must be placed in directy under DATA folder like default models.txt. *~The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. renamekey {key} {newname} *~This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. *~{key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. *~{newname} is the new name for the key. Don't forget to use underscore for spaces. disablekey {key} *~This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. *~{key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. fontmonospace {1} {2} {3} {4} {5} {6} {7} {8} *~This command sets whether font# is monospaced or not. *~{1} refers to font.gif, {2} refers to font2.gif and so on. *~Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. maxscriptvars {int} *~Defines maximum number of variables in each script which is accessible by index. *~Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. maxentityvars {int} *~Defines maximum number of variables in each entity which is accessible by index. *~Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. maxindexedvars {int} *~Defines maximum number of global variables which is accessible by index. *~Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. maxglobalvars {int} *~Defines maximum number of global variables which is accessible by name. *~Default value is 2048. *~Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. *~If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be. alwaysupdate {bi} *~This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc *~Use this command together with update.c of course nocmdcompatible {bi} *~ When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. *~ Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> *~Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> *~Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== name {name} *~{name} is the name given to the entity by default. *~Used for every kind of entities. *~It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. *~If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. *~OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. *~It is mandatory. How would OpenBoR access this entity if there's no name? *~Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. type {type} *~{type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. subtype {type} *~{type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. health {int} *~{int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). *~This is the total amount of damage this entity can take before they die. *~Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. *~You can use decimal numbers, but it will always round down, so there's no real point. *~If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. *~If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. *~Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. *~Used for players, enemies, items, projectiles, obstacles. *~For items, this tells you how much life you regain when you pick it up. mp {int} *~{int} is an integer, a number from -2147483647 to 2147483647. *~This is the total amount of MP this entity begins with. *~MP is drained by attacks set to drain MP. It can be recovered in several ways. *~You can use decimal numbers, but it will always round down, so there's no real point. *~If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. *~Not required. If a player doesn't have it, they won't have an MP bar displayed. *~Used for players and items. *~For items, this tells you how much MP you regain when you pick it up. speed {int} *~{int} is a number from 5 to 300. *~You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. *~Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. *~Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. *~Used for players, enemies, projectiles, and arrows. *~This command doesn't support decimals though. For decimal value, use 'speedf' below. speedf {float} *~Determines entity's speed. *~This have same effect with 'speed' but this one allows {int} less than 5 even negative value. *~Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. running {speed} {height} {length} {move} {land} *~Determines the character's running abilities. *~Used for players and enemies with subtype chase. *~If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. *~If this is not present, the character will be unable to run. *~{speed} is an integer value which works just like speed. *~Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. *~{height} determines how high a character can jump (if at all) while running. It works like jumpheight. *~{length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. *~{move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. *~{land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. nomove {move} {flip} *~Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. *~{move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. *~NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all *~If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). *~NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. jumpspeed {int} *~This command determines entity's jump speed. This entity must be able to jump obviously. *~This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. jumpspeedf {float} *~This command determines entity's jump speed. *~This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. jumpheight {int} *~{int} is an integer value which determines how high an entity jumps. *~The default value is 4. *~An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. *~For Bomb entities, this controls how high the bomb arcs into the air. jumpmove {fx} {fz} *~This allows Player to modify player's jump movement. *~{fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. *~{fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. walkoffmove {fx} {fz} *~This allows Player to modify player's walkoff movement. *~it works like jumpmove {fx} {fz} and params are the same meaning. turndelay {int} *~ This sets how long the character performs BACKWALK before turning back. *~ {int} is time in centiseconds. *~ This is used together with TURN and BACKWALK. facing {int} *~ This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. *~ Setting this allows players to play BACKWALK. chargerate {int} *~Determines how fast MP recharge with CHARGE animation would be. Default value is 2. mprate {int} *~This sets how many MP player recovers (by time and by hitting enemy) *~If typemp = 1, this is the amount MP player recover from hitting enemy. *~If typemp = 2, this is the amount MP player recover on regular intervals. mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate} *~This command determines how MP works for this entity. It's combination of many existing features actually but it has new features *~{mp} sets maximum MP (just like 'mp' command) *~{stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. *~{stable} sets stable MP value. Only usable if {stable type} is not set to 0 *~{recover rate} sets MP recovery rate *~{drop rate} sets MP loss rate *~{charge rate} sets MP recharge rate while entity is charging edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max} *~Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. *~{Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} *~{Factor} is the value you want to apply to delay. *~{Cap Min} is possible shortest delay. *~{Cap Max} is possible longest delay. *~{Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. *~{Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. nohithead {int} *~set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 backpain {int} *~set backpain 1 in entity.txt to activate all backpain animations summonkill {type} *~Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. *~{type} *~Default: 0 *~Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. cmd {sequence of inputs} {freespecial#} *~This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. *~{sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. *~{freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. *~Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. *~{sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== grabdistance {int} *~{int} determines many things: *~How close this entity must be to another to grab it. *~How far away this entity will stand while holding an enemy. *~How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). *~How close this entity must get to be stopped by obstacles or pick up items. *~How close other entities must be to be damaged or blocked by this trap/obstacle. *~The default value is 36. grabback {bi} *~If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. grabfinish {bi} *~This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. *~Use this with GRAB animation of course. grabwalk {bi} *~Determines grabwalking speed. If not declared, entity's walking speed will be used instead. *~You need to declare GRABWALK to use this obviously. grabturn {bi} *~Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. *~If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. *~If GRABTURN is available, it will be played while turning. cantgrab {bi} *~{bi} determines whether or not an entity can be grabbed and held (or thrown). *~If set to 1, opponent who stand close to this entity will simply pass through. paingrab {bi} *~For enemies. *~Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. antigrab {value} *~This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. *~Used in conjuction with 'grabforce'. grabforce {value} *~This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. *~Used in conjuction with 'antigrab'. grabflip {value} *~This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) *~Use this together with grab ability of course throwdamage {int} *~Changes the amount of damage this entity recieves if it gets thrown. *~Defaults to 21. throw {dist} {height} *~Controls the angle at which this player or enemy flies if they get thrown. *~{dist} is the distance that this entity will fly. *~{height} controls how high off the ground this entity will get before it starts falling back down. throwframewait {frame} *~Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== height {alt} *~Affects an entity's ability to walk under platforms. *~If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). *~{alt} is measured from the offset point up. *~This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). antigravity {value} *~This command determines how strong this entity resists gravity. *~Value is in percent so setting 100 makes the entity never fall after jumping. bounce {bi} *~Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set noquake {b1} {b2} *~Determines whether or not the screen shakes if the entity hits the ground after being thrown. *~{b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. *~{b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. no_adjust_base {bi} *~This command determines how terrain effect entity's base altitude. *~Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. subject_to_basemap {bi} *~This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. *~This should be used by AI controlled entities. subject_to_wall {bi} *~This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. *~This should be used by AI controlled entities. subject_to_hole {bi} *~This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. *~Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. *~For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. subject_to_obstacle {bi} *~This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. *~This should be used by AI controlled entities. subject_to_platform {bi} *~This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. *~This should be used by AI controlled entities. subject_to_gravity {bi} *~This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. subject_to_screen {bi} *~This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. subject_to_minz {int} *~This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. subject_to_maxz {int} *~This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. offscreenkill {value} *~Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. *~For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. *~In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. *~{value} is distance in pixels measured from screen edges (left, right, up and down). *~Default value for normal entities is 1000, for arrows and projectiles it's 200 and for bikers it's 300. ==Entity Interaction== aggression {value} *~For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. *~Positive value reduces pausetime making the enemy reacts faster. *~Negative value increase pausetime making the enemy reacts slower. hitenemy {canhit} {alt} *~For enemy's projectile entities. *~If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. *~If {canhit} is 0 or left out, this entity can only hit heros. *~If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. *~{alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. aimove {type} *~This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. *~Default AI is enemy will go after player or other entity he/she/it is hostile to *~Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. *~Accepted 2nd params for {type} are: **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. *~Example: aimove chase notargetidle *~Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one hostile {type1} {type2} ... *~Optional. *~Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). *~Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. *~Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. *~Also 'stealth' feature below affect if the entity will target certain other entities or not. candamage {type1} {type2} ... *~Optional. *~Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). *~Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. *~Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. projectilehit {type1} {type2} ... *~Optional. *~Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. *~Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. *~Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. stealth {stealth} {perception} *~This command sets stealth ability to entity *~{stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 *~{perception} defines how well entity can see stealth entities. Default value is 0 *~For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher *~This command doesn't affect visual at all IOW entity is still visible to players attackthrottle {rate} {time} *~rate: chance to cancel attack (must be between 0.0 and 1.0) *~time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. *~note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. *~the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness boomerangvalues {acceleration} {horizontal_distance} *~acceleration: the float value for de/acceleration of the boomerang *~horizontal_distance: the float value max distance from the spawner and boomerang *~speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== remap {path1} {path2} *~Allows you to create alternate palletes for entities. *~Each entity can have up to 14 palletes. *~{path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. *~You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. *~Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. *~If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. *~In truecolormode (see video.txt above), this command works same way. fmap {int} *~{int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). *~You have to declare that remap with 'remap' before using this obviously. *~If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. *~If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. palette {path} *~This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. *~{path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. *~If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. *~Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using *~If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette *~Useful to create effect libraries without having to design public palette for all of those effects alternatepal {path} *~This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. *~{path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. *~Used in conjunction with 'pallette' above. hmap {a} {b} *~Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. *~Hidden remaps are from ath remap to bth remap. *~For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. globalmap {int} *~This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. KOMap {map} {flag} *~Used to change entity's remap when KO'ed or killed. *~{map} is the remap number to be applied. *~{flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== shadow {int} *~{int} is a number from 0 to 6. *~Each number corresponds to a specific shadow in the SPRITES folder. *~Normally, the lower numbers are smaller. *~This determines which shadow graphic will appear centered at this entity's offset point. *~0 means there won't be a shadow. aironly {bi} *~If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) gfxshadow {int} {shadowbase} *~Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). *~{shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty alpha {int} *~If set to 1, this entity will be displayed with alpha transparency. *~If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). *~If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". *~If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". *~If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." *~If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. *~In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. parrow {path} {x} {y} *~When a player respawns, the image at {path} will flash over the player at {x},{y} compared to their offset. *~The image will be visible for as long as the player is invincible after respawning (determined with makeinv). *~I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. parrow2 {path} {x} {y} *~If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. diesound {path} *~{path} points to a .wav file that plays if the entity is defeated. *~It is also played if entity is killed instantly with lifespan or script. setlayer {int} *~This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== load {name} *~This forces engine to load other entity into memory so the entity can be used. *~{name} is name of loaded entity. *~Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. *~Before using this, the entity must be declared with 'know' in models.txt. playshot {name} *~{name} is the name of an entity. *~The player shoots this with pshotframe #. *~This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. playshotno {name} *~{name} is the name of an entity. *~The player shoots this with 'pshotframe #'. *~Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. *~That also means setting a in 'pshotframe' is useless. knife {name} *~Used like "load". {name} will be thrown like a knife. *~You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. *~Knives can't be used by enemies during a jump. Stars are currently thrown instead. boomerang {name} *~Used like "load". {name} will be thrown like a boomerang. *~You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. star {name} *~Used like "load". {name} will be flung like a ninja star in a jump. *~This command actually causes three stars to be thrown at three different angles. *~You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. *~Stars can only be used during a jump. bomb {name} pbomb {name} *~This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". *~Used like "load". {name} will be tossed out like a grenade. *~Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground *~After 1 or 2, the bomb will play it's ATTACK2 animation. *~After 3, the bomb will play it's ATTACK1 animation. *~After playing it's attack animation, the bomb will disappear. *~Bombs are thrown in an arc determined by their speed and their jumpheight. *~You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. rider {name} *~For 'subtype biker' enemies. *~{name} should be the name of an enemy in MODELS.txt. *~When the bike is attacked, this entity will fall off. *~Defaults to "K'" (Yes, with an apostrophe ') *~If the rider is only loaded with 'know' in models.txt, you should add 'load {name}' in this biker text to ensure that the 'rider' will fall off. ==Flash== flash {name} *~{name} is the name of flash animation this entity will use. Defaults to "Flash". *~This is played when this entity is hit, not when it hits another entity. *~'noatflash' is required to make this command is activated. bflash {name} *~{name} is the name of flash animation this entity will use. Defaults to "Flash". *~This is played when this entity blocks an attack. dust {fall} {land} {jump} *~This command defines what dust entity which will be dropped by this entity on certain conditions below. *~Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. *~{fall} is the dust dropped when entity landed on ground after being knocked down. *~{land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. *~{jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. *~If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. toflip {bi} *~Used for hitflashes. *~If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. noatflash {bi} *~When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== com {input1} {input2} ... {input15} freespecial{#} *~Allows you to customize freespecial input commands. *~The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. *~If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. *~{input#} defines which key must be pressed. It can be direction or action keys *~Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) *~Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button *~You can define same input multiple times if you want to, example: F F A *~You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) *~Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. *~If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. *~{input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> atchain {number} {number} {number} {number} {number} ... *~Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. *~The maximum length is 12. How they are used are determined by 'combostyle' below. *~{number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. *~You can repeat the same number if you need to. *~You don't have to use all of them. Setting something like 'atchain 1 3 2' works. *~Default combo is 'atchain 1 1 2 3'. combostyle {bi} *~Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system *~With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. *~The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. *~With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) offense {type} {factor} *~Modifies damage output of given attack type by {factor}. *~For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. *~{factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. *~Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype} *~Modifies damage received by given attack type by {factor}. *~For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. *~{factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. *~Accepted types are exactly sames with 'offense' (see above). *~{pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN *~{knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. *~{blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. *~{blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. *~{blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. *~{blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP blockodds {int} *~{int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. *~1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. *~Enemies can't block during attacks so don't hesitate using this ;). thold {int} *~{int} is the threshold for an entity's blocking ability. *~If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. *~If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. *~Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. blockpain {int} *~Determines how strong entity blocks incoming attack during blocking. *~If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. *~Use this with BLOCK animation of course. nopassiveblock {bi} *~Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. *~Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. *~Obviously entity who use this must have block ability. holdblock {int} *~Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. *~Use this command with block ability of course. Work in conjunction with Blockpain animations. guardpoints {int} *~Defines amount of guardpoints this entity has. *~When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. *~If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. *~Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. *~This feature works with BLOCK animation and custom blocks with script. guardrate {int} *~Defines recovery rate of 'guardpoints' above. Default value is 2. *~Use with 'guardpoints' of course. offscreen_noatk_factor {bi} *~This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. *~0 Means that the entity can attack outside the visible area (default) *~1 Means that the entity CAN NOT attack outside the visible area. *~If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== nopain {bi} *~Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. nodrop {int} *~Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. *~This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. *~Throwing with THROW can still knockdown this entity. *~If this entity dies, he/she will play FALL animation or DEATH if it's available and set. knockdowncount {int} *~This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. *~If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. *~If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. remove {bi} *~Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. escapehits {int} *~For enemies *~If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. *~In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. *~The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. nodieblink {int} *~Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. makeinv {int} {bi} *~Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. *~(int) is how many seconds the player will be invincible for. *~(bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking *~{int} also controls how long the parrow and parrow2 are visible. *~You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. falldie {value} or death {value} *~Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. *~MAKE SURE that the character have DEATH animation when using this! risetime {rise} {riseattack} *~Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default riseattacktype {int} *~Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). riseinv {int} {bi} *~Determines whether or not the player is briefly invincible after rising. *~(int) is how many seconds the player will be invincible for. *~(bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking jugglepoints {int} *~This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. *~Juggling means attacking falling opponents (assuming they are vulnerable while falling). *~This command is used in conjunction with 'jugglecost' (see Animation Data below). *~The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. *~If {int} is set to -1, the entity will be immune to juggles. instantitemdeath {int} *~ This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== weapons {name1} {name2} {name3} {name4} {name5} {original name} *~This command sets other model which will be used to replace this entity when a weapon is picked up. *~{name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. *~{original name} is the name of the character when it doesn't have any weapons equipped. *~If {name#} is filled with none, this entity can't pick respective weapon. project {name} *~For subtype "project" items. *~{name} is the name of the new projectile the player or enemy who grabs this can use. shootnum {int} *~For items which can be used as weapons. *~This is the maximum number of times a weapon can be fired. counter {int} *~For items which can be used as weapons. *~This is the maximum number of times a weapon can be dropped before it dissapears forever. *~To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! reload {int} *~For items. *~If a player picks up an item that has this command, it will restore their ammunition by {int}. *~Does nothing if a player doesn't have a weapon. *~Should be used with 'shootnum'. *~Don't forget that items can only give one bonus. typeshot {bi} *~For weapons. *~Determines if the weapon is a gun or a knife. *~0 means a knife, and ammunition will not be displayed, since you can only throw knives once. *~1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. animal {bi} *~For players with a weapon. *~Determines if the weapon is actually an animal to be ridden. *~Animals will run away if they are knocked down enough times. *~Players on an animal can't be grabbed. weaploss {flag} {weapnum} *~Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) *~This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. modelflag {int} *~Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied *~Use this with weapon models of course. weapnum {int} *~Used to give number to weapons. {int} is the number. *~Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== icon {path} {bi} *~The graphic normally shown next to the entity's life bar. *~Normally a 16 x 16 box with a picture of the entity's head. *~{path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. *~The position of the graphic can be changed in LEVELS.txt. *~You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. *~Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 iconpain {path} *~Same as icon, except this appears instead if the entity is being injured. *~This only works for players. icondie {path} *~Same as icon, except this appears instead if the entity is dead. *~This only works for players. iconget {path} *~Same as icon, except this appears instead if the entity is picking up an item. *~This only works for players. Not like anything else has a GET animation. iconw {path} *~For players with a weapon. *~{path} should point to a .gif file. *~If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. iconmphigh {path} *~Same as icon, except this appears when the entity's MP is full. *~This only works for players. Other entities doesn't have MP. iconmphalf {path} *~Same as icon, except this appears when the entity's MP is half. *~This only works for players. Other entities doesn't have MP. iconmplow {path} *~Same as icon, except this appears when the entity's MP is low. *~This only works for players. Other entities don't have MP. nolife {bi} *~Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. lifebarstatus {w} {h} {noborder} {type} {orientation} {border} {shadow} {graph} {backfill} *~This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. *~If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. *~This settings is not affected by 'nolife' (see above) at all. *~{w} is the maximum amount of health the bar can display. Defaults to 100. *~{h} is the height of the lifebar in pixels. Defaults to 5. *~{noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. *~{type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. *~{orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. *~ {border} sets layer adjustment of outer border. Default to 0. *~{shadow} sets layer adjustment of border shadow. Default to 0. *~{graph} sets layer adjustment of graph fill. Default to 0. *~{backfill} sets layer adjustment graph background. Default to 0. *~The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. lifeposition {x} {y} *~This command determines display position of entity's lifebar onscreen. *~It is counted from upperleft corner of screen to lifebar's upperleft corner. *~Use this together with 'lifebarstatus' above. nameposition {x} {y} *~This command determines display position of entity's name onscreen. *~It is counted from upperleft corner of screen to name's upperleft corner. *~Use this together with 'lifebarstatus' above. iconposition {x} {y} *~This command determines display position of entity's icon onscreen. *~It is counted from upperleft corner of screen to icon's upperleft corner. *~Use this together with 'lifebarstatus' above. ==Miscellaneous== credit {int} *~For items. *~If an item has this set, it will give player credit when player take it. *~Keep in mind that only one bonus can be given to an item. secret {bi} {int} *~Used to make a 'secret' character who must be unlocked before he/she can be played *~{bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) *~{int} defines how many times game must be completed before the character is unlocked *~Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) sleepwait {value} *~Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. score {onkill} {multiplier} *~Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. *~When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. *~Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. *~The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. *~When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. smartbomb (power) (type) (pause) (length} *~This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! *~If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. *~{power} is an integer value which determines attack damage. *~{type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal *~{pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. *~If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. *~This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} *~Exactly what is so smart about a bomb that just hits everything, anyway? branch {name} *~This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. *~{name} is name of the destination in a level set. *~In case you haven't figure it out, this feature is to make branch for multiple paths. lifespan {value} *~Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. *~After {value} expires, entity will die and will play entity's death animation if the entity has it. *~Entity who uses this can die normally if {value} hasn't expired of course. scroll {value} *~Used to make non panel typed entities scroll like panel type. *~{value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== WAITING (used for players) *~An optional animation. *~Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). SELECT (used for players) *~An optional animation. *~Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). SPAWN (used by all entities) *~An optional animation. *~Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. *~For players, this is only played when they are spawned to level for 1st time. *~It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. RESPAWN (used by all entities) *~An optional animation. *~For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. *~For players, this is only played when they are respawned to level after losing life. IDLE (used by all entities) *~The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. *~Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. *~If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. *~Entity can have more IDLE animations, see below. IDLE# (used by all entities) *~Played if there's opponent within set 'range' while in IDLE. *~# is the number of animation. Do not type # but type a number instead. *~For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. *~If there are multiple IDLE# animations, the one with lowest number has the highest priority. *~Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). *~These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! FAINT (players, enemies) *~Optional. *~If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. SLEEP {players} *~Optional. *~It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. *~If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. *~It will be overridden by FAINT, if FAINT is available too. WALK (players, enemies, projectiles) *~Optional for non-moving enemies. They won't use it, so why give it to them? *~The animation for an entity walking left or right. *~If a character does not have UP and DOWN animations, they will use this instead when walking up or down. *~Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. *~Entity can have more WALK animations, see below. WALK# *~Played if there's opponent within set 'range' while in WALK. *~Works just like IDLE# above except it's for WALK. *~Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). WALKOFF {players, enemies} *~Optional *~This animation is played when entity walks off platforms or walls *~WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) BACKWALK {players, enemies} *~Optional. *~Players play this only if they have 'facing' set. *~Enemies will play this if they move backwards while facing players. *~Entity can have more BACKWALK animations, see below. BACKWALK# *~Played if there's opponent within set 'range' while in BACKWALK. *~Works just like IDLE# above except it's for BACKWALK. *~Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). TURN *~Optional. *~For players and enemies. *~This animation will be played when players or enemies turn back after walking backwards with BACKWALK. UP {players, enemies} *~Optional. *~Played when the character walk up, up-left, or up-right. *~For this animation to work correctly, it must have the same number of frames as the WALK animation. *~Entity can have more UP animations, see below. UP# *~Played if there's opponent within set 'range' while in UP. *~Works just like IDLE# above except it's for UP. *~Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). DOWN {players, enemies} *~Optional. *~Played when the character walk down, down-left, or down-right. *~For this animation to work correctly, it must have the same number of frames as the WALK animation. *~Entity can have more DOWN animations, see below. DOWN# *~Played if there's opponent within set 'range' while in DOWN. *~Works just like IDLE# above except it's for DOWN. *~Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). DUCK {players, enemies} *~Optional. *~This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). *~Plays when a player presses down. They can use this to duck under high attacks. *~This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. *~While ducking, player can perform either SLIDE or DUCKATTACK (see below). *~If DUCKING is present (see below), this animation will play after it. *~For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. DUCKING {players, enemies} (6330+) *~Optional. *~This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. *~After this animation ends, the entity will go to DUCK if the hold button is held. *~Same rules of DUCK appliess here. DUCKRISE {players, enemies} (6330+) *~Optional. *~This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. *~Same rules of DUCK appliess here. LAND (players) *~Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. *~If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. RUN (players, enemies) *~Optional. *~If the player has their running speed specified, this is the animation they will use to run. *~To perform this, tap forward twice then hold forward to keep running. *~By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. *~This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. BACKRUN (players, enemies) *~Optional.(4310+) *~To active it set facing {flag} at entity header. *~Using back,back or forward,forward (in opposite direction) you'll enter in backrun JUMP {players, enemies} *~Plays when a player presses jump or when an enemy approaches a platform. *~You don't need to draw the entity moving upward, since BoR moves them automatically. *~If given to an enemy, this animation should also have a range listed. *~Every jump animations including this will keep playing until the character lands regardless how long the animations are. JUMPDELAY {players, enemies} *~Optional. *~Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. *~It won't be used if entity jumps with 'jumpframe'. JUMPLAND {players, enemies} *~Optional. *~Played after entity lands from normal jump. *~It won't be used if entity jumps with 'jumpframe'. FORWARDJUMP {players, enemies} *~Optional. *~Played when entity jumps forward with normal jump. *~It won't be used if entity jumps with 'jumpframe'. RUNJUMP (players) *~Optional. *~Played when entity jumps forward while running with normal jump. *~It won't be used if entity jumps with 'jumpframe'. DODGE (players) *~Optional. *~Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. *~The player will move along the z axis (closer to or farther from the screen). *~The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. *~This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. GET {players, enemies} *~Optional. *~Played when the character picks up an item. JUMPCANT {players} *~Optional. *~This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. CHARGE {players} *~Optional. *~Despite its name, this animation is not related to CHARGEATTACK at all. *~This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. *~While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). CANT (players) *~Used with MP. *~If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. *~If the attack they were using had the Special button as input, they will block instead of playing this animation. GRAB {players, enemies} *~Optional for enemies and players. *~When this entity moves close enough to another, this entity will grab hold of the other. *~If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. *~If you don't want this entity to be able to grab, just don't give them this animation. GRABWALK (players) *~Optional. Currently only used by players. *~This animation is played when player walks while grabbing enemy. *~The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. *~This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. GRABBACKWALK (players) *~Optional. Currently only used by players. *~This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. *~The grabbackwalk speed is also determined by 'grabwalk' (see above). *~This animation is like WALK animation so setting 'loop 1' is recommended. GRABWALKUP (players) *~Optional. *~This animation is played when player walks upwards (in z axis that is) while grabbing enemy. *~The grabbackwalk speed is also determined by 'grabwalk' (see above). *~This animation is like WALK animation so setting 'loop 1' is recommended. GRABWALKDOWN (players) *~Optional. *~This animation is played when player walks downwards (in z axis that is) while grabbing enemy. *~The grabbackwalk speed is also determined by 'grabwalk' (see above). *~This animation is like WALK animation so setting 'loop 1' is recommended. GRABTURN (players) *~Optional. *~This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. *~During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. SLIDE {players} *~Optional. *~This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. RUNSLIDE {players} *~Optional. *~This animation is performed by pressing DOWN+JUMP while running or in RUN animation. EDGE {players} (6330+) *~Optional. *~This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. BACKEDGE {players} (6330+) *~Optional. *~Works like EDGE animation, but happens when the edge is behind of the player. VICTORY {players} (6330+) *~Optional. *~This animation is performed when you defeat all bosses in a level. LOSE {players} (6330+) *~Optional. *~This animation is performed when you got a time over. ==Attack== ATTACK1 {players, enemies} *~By default, this animation is NOT optional for players. It is optional for enemies. *~An attack. Players perform this by pressing attack (unless the chain order is changed). *~Enemies perform this attack when a player is in range (range is specified with the 'range' command). *~Enemies are slightly more likely to use ATTACK1 than ATTACK2. *~Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. ATTACK2 {players, enemies} *~By default, this animation is NOT optional for players. It is optional for enemies. *~Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). *~Enemies use this just like ATTACK1. *~Enemies are slightly more likely to use ATTACK2 than ATTACK3. *~Enemy bombs play this animation if they touch another entity's bbox or attack box. ATTACK3 {players, enemies} *~By default, this animation is NOT optional for players. It is optional for enemies. *~And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) *~This animation is also played instead if grab finishers and chargeattack are not available.. *~Enemies use this just like ATTACK1 and ATTACK2. ATTACK4 {players, enemies} *~Optional. *~Players use this only if it is included in 'atchain' . *~Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. ATTACK5,ATTACK6,... {player,enemies} *~These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). *~After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. CHARGEATTACK {players} *~Optional. *~This attack is unleashed after holding attack button for about 3 seconds then let it go. *~If this is not available, the last attack in player's attack chain will be played instead. ATTACKBOTH {players} *~Optional. *~An attack. Players use this if they hold attack and then press jump. *~This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. UPPER {enemies} *~Optional. *~If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. *~Range command (see Animation Data below) can be used for this attack although it's not necessary. RUNATTACK {players} *~Optional. *~Requires the character to be able to run. Otherwise, they can't really use it. *~If the player presses attack while running, they will perform this attack. *~Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. RUNJUMPATTACK {players} *~Optional. *~Requires the character has a RUN animation. Otherwise, they can't really use it. *~If the player presses attack during a running jump, they will perform this attack. JUMPATTACK {players, enemies} *~An attack. *~For players, this is the attack performed when a player jumps and presses attack. *~Enemies randomnly perform this attack when a player is in range. *~The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. *~When enemies use this attack, they'll jump forward. JUMPFORWARD {players} *~Optional. *~If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. JUMPATTACK2 {players, enemies} *~An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. *~Enemies randomnly perform this attack when a player is in range. *~When enemies use this attack, they'll jump straight up. JUMPATTACK3 {players} *~Optional. *~An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. JUMPSPECIAL/SPECIAL3 {players} *~Optional. *~An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. *~Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. *~This animation can be disabled with 'type' in level texts. See 'Level files' below for more info ATTACKUP {players} *~Optional. *~An attack. Players perform this by pressing up twice. *~This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. ATTACKDOWN {players} *~Optional. *~An attack. Players perform this by pressing down twice. *~This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. ATTACKFORWARD {players} *~Optional. *~An attack. Players perform this by pressing forward twice. *~This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. ATTACKBACKWARD {players} *~Optional. *~An attack. Players perform this by pressing backwards once, then quickly pressing attack. *~Unlike most attacks which use the back button, this does not flip your direction. FOLLOW{#} {players,enemies} *~Optional. *~{#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. *~It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. FOLLOW5,FOLLOW6,... {player,enemies} *~These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). *~After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. FREESPECIAL{#} {players, enemies} *~Optional. *~If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. *~There is no space between FREESPECIAL and {#}. *~An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. *~FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. *~For enemies, this animation works just like normal attack animations. FREESPECIAL9,FREESPECIAL10,... {player,enemies} *~These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). *~After they are available, they work just like other FREESPECIALs. SPECIAL {players, enemies} *~Optional for enemies. *~A breakout attack. *~Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. *~For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). *~Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. *~For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info SPECIAL2 {players, enemies} *~Optional. *~Players perform this by pressing forward and special, or special while running. *~Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. *~For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info GRABATTACK {players, enemies} *~Optional for enemies, can be made optional for players with cantgrab or notgrab. *~When you've grabbed another character, you can press attack to use this attack up to two times. GRABATTACK2 {players, enemies} *~Optional. If not defined, defaults to ATTACK3. *~When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. *~You can also use this early by pressing jump. GRABFORWARD {players} *~Optional. *~When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. GRABFORWARD2 {players} *~Optional. If not defined, defaults to ATTACK3. *~When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. *~You can't use this early by pressing jump and forward. GRABUP {players} *~Optional. *~When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. GRABUP2 {players} *~Optional. If not defined, defaults to ATTACK3. *~When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. *~You can't use this early by pressing jump and up. GRABDOWN {players} *~Optional. *~When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. GRABDOWN2 {players} *~Optional. If not defined, defaults to ATTACK3. *~When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. *~You can't use this early by pressing jump and down. THROW {players, enemies} *~Optional. *~When you've grabbed another character, you can press back and attack to use this attack. *~By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. *~The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. *~The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! GRABBACKWARD {players} *~Optional. *~When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. *~Since it has same command as THROW, don't use them both to avoid confusion! GRABBACKWARD2 {players} *~Optional. *~When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. *~You can't use this early by pressing jump and back. *~Since it has same command as THROW, don't use them both to avoid confusion! DUCKATTACK {player} *~Optional. *~This animation is performed if attack is pressed while player is ducking. *~It can also be played when player is forced to duck like under platform. ==Reaction== PAIN{#} {players, enemies} *~Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. *~{#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. *~This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. *~PAIN is mandatory while PAIN2, PAIN3 etc are optional. *~If required PAIN{#} is not available, PAIN will be used instead. *~This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. PAIN11,PAIN12,... {player,enemies} *~These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other PAINs. BACKPAIN{#} {players, enemies} *~Played when an entity is hit from behind by an attack which does not knock them down. *~{#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. *~This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. *~To enable this, you need to add BACKPAIN 1 to entity header SPAIN {players, enemies} *~Optional. Defaults to PAIN. *~No, not Spain. It stand for Shocked PAIN. *~Played when an entity is hit by a shock attack which does not knock them down. BPAIN {players, enemies} *~Optional. Defaults to PAIN. *~This means Burned PAIN. *~Played when an entity is hit by a burn attack which does not knock them down. FALL{#} {players, enemies, obstacles} *~Played when an entity is knocked down by a knock down attack. *~{#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. *~This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. *~FALL is mandatory while FALL2, FALL3 etc are optional. *~If required FALL{#} is not available, FALL will be used instead. *~Declaring 'bbox' in this animation allows entity to be juggled. *~Entities can't be grabbed (by walking to them) in this animation. *~This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. FALL11,FALL12,... {player,enemies} *~These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other FALLs. BACKFALL{#} {players, enemies, obstacles} *~Played when an entity is knocked down by a knock down attack from behind. *~To enable this, you need to add BACKPAIN 1 to entity header *~Follow the same logic of FALL animation RISE{#} {players, enemies} *~Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). *~{#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. *~This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. *~RISE is mandatory while RISE2, RISE3 etc are optional. *~If required RISE{#} is not available, RISE will be used instead. RISE11,RISE12,... {player,enemies} *~These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other RISEs. RISEB {players, enemies} *~Optional. *~Played when an entity is rising after falling with BURN animation. RISES {players, enemies} *~Optional. *~Played when an entity is rising after falling with SHOCK animation. BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies} *~Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) *~Respective backpain animations RISEATTACK{#} {players, enemies} *~Optional. *~Players play this instead of RISE if Up+Attack is pressed before they rise. *~Enemies play this immediately if a player is in range of the attack while they are lying on ground. *~{#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. *~This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. *~How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies} *~Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) *~Respective backpain animations RISEATTACK11,RISEATTACK12,... {player,enemies} *~These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other RISEATTACKs. RISEATTACKB {players, enemies} *~Optional. *~Played when an entity is riseattacking after knocked down with burn attack before. RISEATTACKS {players, enemies} *~Optional. *~Played when an entity is riseattacking after knocked down with shock attack before. SHOCK {players, enemies} *~Optional. Defaults to FALL. *~Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. BACKBPAIN, BACKSPAIN *~Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) *~Respective backpain animations for burn/shock during pain BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN *~Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) *~Respective backpain animations for burn/shock during fall BURN {players, enemies} *~Optional. Defaults to FALL. *~Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. DEATH{#} {players, enemies, obstacles} *~Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. *~Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. *~How this animation will be played is controlled by 'falldie/death' (see Header Data above). *~{#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. *~If an entity is killed by being thrown, they will not use this animation. DEATH11,DEATH12,... {player,enemies} *~These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other DEATHs. BACKDEATH{#} {players, enemies, obstacles} *~To enable this, you need to add BACKPAIN 1 to entity header *~Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. *~Follow the same logic of DEATH BDIE {players, enemies} *~Optional. *~Played when the character is finished by 'burn'. *~It's still controlled by 'death' though. SDIE {players, enemies} *~Optional. *~Played when the character is finished by 'shock'. *~It's still controlled by 'death' though. CHIPDEATH {players} *~Optional. *~Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. BLOCK (enemies, players) *~Optional. *~For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. *~Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. *~Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). *~Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. BLOCKPAIN{#} {players,enemies} *~Optional. *~Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. *~{#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. *~This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. *~If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. BLOCKPAIN11,BLOCKPAIN12,... {player,enemies} *~These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other BLOCKPAINs. BLOCKPAINB {players, enemies} *~Optional. *~Played when an entity received too much damage from 'burn' attack while blocking. BLOCKPAINS {players, enemies} *~Optional. *~Played when an entity received too much damage from 'shock' attack while blocking. GUARDBREAK {players, enemies} *~Optional. *~Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. GRABBED {players, enemies} *~Optional. Defaults to the PAIN animation if not present. *~Plays when this character is grabbed by another. GRABBEDWALK (players,enemies) *~Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. *~This animation is played when entity is being held and grabbing player is grabwalking. GRABBEDBACKWALK (players,enemies) *~Optional. I hope the name doesn't confuse you. *~This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. GRABBEDWALKUP (players,enemies) *~Optional. If the name confuses you, try reading it slowly. *~This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. GRABBEDWALKDOWN (players,enemies) *~Optional. If the name confuses you, try reading it slowly. *~This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. GRABBEDTURN (players,enemies) *~Optional. *~This animation is played when entity is being held and grabbing player is grabturning. HITWALL (players,enemies) *~Optional. *~This animation is played when entity hits a wall while falling. HITPLATFORM (players,enemies) *~Optional. *~This animation is played when entity hits a platform while falling. HITOBSTACLE (players,enemies) *~Optional. *~This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== @include *~ With this tag, you can import another animation text file to the current animation (build 3842+). *~ For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> *~ Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> loop {bi} {start} {end} *~Determines how loop effect is applied in current animation *~{bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on *~{start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. *~{end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. *~Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. fastattack {bi} *~Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. *~If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). blockfx {path} *~{path} should point to a .wav file. *~If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). *~Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. blockflash {name} *~{name} is the name of an entity declared in MODELS.txt. *~If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). bflash {name} *~{name} is the name of an entity declared in MODELS.txt. *~ Does the same of above. blockflash command is old and coded before bflash. range {min} {max} *~Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. *~This command lets the entities know when to perform their attacks or to jump on platforms. *~For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. *~Entity's opponent is determined by 'hostile' setting (see Header Data above). *~For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. *~This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. *~If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. *~For homing projectiles, this determines their targeting range. *~If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. *~Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. *~Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range rangez {min} {max} *~This command works similar with 'range' (see above) except that it works in z axis instead. *~Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. *~If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. rangea {min} {max} *~This command works similar with 'range' (see above) except that it works in y axis or altitude instead. *~Default values for {min} and {max} are -1000 and 1000 respectively. *~If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. rangeb {min} {max} *~This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. *~Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. *~Default values for {min} and {max} are -1000 and 1000 respectively. *~If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. dive {hori} {vert} *~Allows characters to dive while in air. So obviously, they need to be in the air for it to work. *~Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. *~NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. *~{hori} controls how fast the diving entity will move forward, horizontally. *~{vert} controls how fast the diving entity will move downward, vertically. *~This command is outdated. Use 'jumpframe' below for better effect. energycost {int} {mponly} {disable} *~Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. *~{mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. *~{disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies *~When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: *~If the player has enough MP to use the attack, it comes from their MP. *~If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. *~If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. *~This command also work with enemies. Since enemies don't have MP, this command will only drain health. *~If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. *~Defaults to 6 for SPECIAL and 0 for anything else. mponly {int} *~Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. mpcost {int} *~When the attack is performed, (int) will be subtracted from the player's MP. *~This command is outdated and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! followanim {value} *~Determines which FOLLOW animation played when followup condition is met or when counter condition is met. *~Possible values are 1, 2, 3 and 4. *~Used together with 'followcond' or 'counterframe'. followcond {value} *~This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. *~value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. *~Which FOLLOW animation played is determined by 'followanim'. attackone {bi} *~This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. counterattack {bi} *~If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. *~Like the name sais, this is great for counter attacks. bouncefactor {r} *~This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. *~{r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. *~Normally this is used in FALL animation however it also works with other animations. *~This command won't have any effect if 'bounce' (see above) is set to 0. animheight {alt} *~This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. *~Defaults to 0 or 'height' if it's not declared. cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#} *~This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. *~This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. *~{start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. *~{hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. *~{sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. *~{freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. *~Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. *~If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. *~If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. *~If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. *~Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. *~{sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> chargetime {int} *~Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. *~{int} is time in seconds. *~ONLY works in CHARGEATTACK animation. sync *~Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. *~Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== pshotframe {frame} {a} *~If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. *~The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. *~The shot is defined by using the 'playshot' command. *~{a} defaults to 70. *~This command is outdated since all entities including players can use throwframe for same purpose. throwframe {frame} {a} *~If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. *~The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. *~The projectile is defined by using the 'star' or 'knife' commands. *~Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *~{a} defaults to 70. *~Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. *~If you want entity to throw knives while entity is airborne use 'shootframe' instead. shootframe {frame} {a} *~This command is similar to 'throwframe' but it shoots 'shot' instead. *~{a} defaults to 0. *~This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. custknife {name} *~{name} is the name of an entity declared in MODELS.txt. *~If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. *~You still need to fire the entity at some point in the animation for this to do anything. *~Don't forget to load the entity in MODELS.txt! *~Knives can't be used by enemies during a jump. custboomerang {name} *~{name} is the name of an entity declared in MODELS.txt. *~If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. *~You still need to fire the entity at some point in the animation for this to do anything. *~Don't forget to load the entity in MODELS.txt! *~Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command custstar {name} *~{name} is the name of an entity declared in MODELS.txt. *~If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. *~You still need to fire the entity at some point in the animation for this to do anything. *~Don't forget to load the entity in MODELS.txt! tossframe {frame} {a} *~These 2 commands have same function but only "tossframe" which works for players and enemies. *~If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. *~The projectile will be spawned at altitude {a}. *~The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *~{a} defaults to 70. custbomb {name} / custpbomb {name} *~Use "custbomb" for enemies and "custpbomb" for players. *~{name} is the name of an entity declared in MODELS.txt. *~If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. *~You still need to fire the entity at some point in the animation for this to do anything. *~Don't forget to load the entity in MODELS.txt! jumpframe {frame} {speedy} {speedx} {speedz} {dust} *~If this command is present, the entity will perform a jump once frame {frame} is reached. *~{speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. *~{dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. *~For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. *~Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. *~With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. *~Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. *~Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. *~Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. dropframe {frame} *~This is used to make entity switch to set {frame} when flight apex is reached while in air. landframe {frame} {dust} *~If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. *~{dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. *~In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. *~Make sure the landing frame exists otherwise the entity will disappear right after landing! flipframe {frame} *~Used to make character turn around when frame+1 is played. *~Management is not responsible for any damage caused of using this command in improper animation such as WALK. quakeframe {frame} {loops} {intensity} *~Used to make screen shakes with certain intensity. *~{frame} determines at which frame the quake/shake starts. *~{loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. *~{intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. *~Negative value works for this and the quake will be new style extreme quake. counterrange {start} {end} {condition} {damage} *~Animation header. If all conditions are met, entity will perform animation set by followanim. This command is outdated and only included for backward compatibility. Use '''Counterrange''' instead. *~This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *~frame determines at which frame if entity is hit , FOLLOW{#} would be played. *~Which FOLLOW animation played is determined by 'followanim'. *~{start} Start of frame range when counter may trigger. *~{end} End of frame range when counter may trigger. *~cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). *~damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken ignoreattackid {int} *~Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! spawnframe {frame} {x} {z} {a} {relative} *~Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. *~The spawned entity is determined by 'subentity' or 'custentity'. *~{frame} determines at which frame the other entity is spawned. *~{x} determines spawn range in x axis. *~{z} determines spawn range in z axis. *~{a} determines spawn range in y axis. *~{relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. *~Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. summonframe {frame} {x} {z} {a} {relative} *~Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. *~The spawned entity is determined by 'subentity' or 'custentity'. *~{frame} determines at which frame the other entity is spawned. *~{x} determines spawn range in x axis. *~{z} determines spawn range in z axis. *~{a} determines spawn range in y axis. *~{relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. *~Summoned entity can be killed with 'unsummonframe'. *~Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. unsummonframe {frame} *~Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. *~{frame} determines at which frame the other entity is spawned. subentity {name} / custentity {name} *~{name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. *~Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. *~This is used together with 'spawnframe' or 'summonframe'. *~{name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. weaponframe {frame} {weapon} *~This is used to switch weapon in an animation. *~{frame} determines at which frame the weapon is switched. *~{weapon} is weapon's number determines which weapon will be used to replace. *~Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== delay {int} *~{int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. *~{int} is measured in centiseconds, or hundredths of a second. Pretty fast. *~Can be used multiple times in one animation to change speed mid-animation offset {x} {y} *~Determines where the "base" of the animation is. *~The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. *~'offset 0 0' would be the upper left corner. Larger {x} values move the {x} down. Larger {y} values move the {y} right. *~You can use negative numbers or numbers outside of the frame's edges. *~Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. *~Can be used multiple times in one animation to change position mid-animation bbox {x} {y} {right} {down} {z} *~Determines where the entity can be hit. *~{x} and {y} are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. {right} is how far to the right of {x} the box extends. {down} is how far down from {y} the box extends. *~{z} determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. *~You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. *~Can be used multiple times in one animation to change hittable areas mid-animation. *~To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. *~For items, this determines where the object can be picked up from. frame {path} *~{path} points to a graphics file to be used in this animation. *~The frame will be displayed at the entity's position. It's about as simple as it sounds. *~OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. *~Image's extension can be omitted (e.g idle instead of idle.gif) *~If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png *~When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) *~For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. *~If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). alphamask {path} *~{path} *~Default: NA *~Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. *~The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: *~The mask must have exactly the same width and height as its corresponding sprite. *~The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. *~If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. *~Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' *~Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' *~'''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. *~At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> attack{#} {x} {y} {right} {down} {damage} {power} {block} {noflash} {pausetime} {z} '''There are two ways to set an attack box, since build 4183:''' the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. *~An attack box which can hit bboxes *~OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. *~You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. *~{x}, {y}, {right}, and {down} work exactly like in a bbox. *~{damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. *~{power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). *~{block} is a binary value which determines if an attack is unblockable. *~{noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. *~{pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. *~{z} determines attackbox' width in z axis. *~If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. *~You can use negative numbers or numbers outside of the frame's edges. *~Can be used multiple times in one animation to change hit areas mid-animation *~When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! *~Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). '''The new method:''' Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. *~attack.block.cost - See guardcost. *~attack.block.penetrate - See attack{#} {block}. *~attack.counter - See counterattack. *~attack.damage.force - The attack's standard damage output. *~attack.damage.land.force - damageonlanding {value} *~attack.damage.land.mode - damageonlanding {type} *~attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. *~attack.damage.recursive.force - See DOT {force}. *~attack.damage.recursive.index - See DOT {index}. *~attack.damage.recursive.mode - See DOT {mode}. *~attack.damage.recursive.rate - See DOT {rate}. *~attack.damage.recursive.time - See DOT {time}. *~attack.damage.steal - Damage done by this attack will be added to attackers HP. *~attack.damage.type - Sets attack type. Same as {#} in attack{#} *~attack.effect.block.flash.model - See blockflash. *~attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. *~attack.effect.hit.flash.disable - See noflash. *~attack.effect.hit.flash.model - See hitflash. *~attack.effect.hit.flash.sound - See hitfx. *~attack.index - Currently no effect. This is for future support of multiple attack boxes. *~attack.ground.mode - See otg. *~attack.map.index - See forcemap {map}. *~attack.map.time - See forcemap {time}. *~attack.position.x - See attack{#} {x}. *~attack.position.y - See attack{#} {y}. *~attack.reaction.fall.force - See attack{#} {power}. *~attack.reaction.fall.velocity.x - See dropv {speedx}. *~attack.reaction.fall.velocity.y - See dropv {speedy}. *~attack.reaction.fall.velocity.z - See dropv {speedz}. *~attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. *~attack.reaction.freeze.time - Time target remains frozen. *~attack.reaction.invincible.time - Time to remain invincible after hit. *~attack.reaction.reposition.direction - See forcedirection. *~attack.reaction.reposition.distance - See grabin {distance}. *~attack.reaction.reposition.mode - See grabin {mode}. *~attack.reaction.pain.disable - See noreflect. *~attack.reaction.pause.time - See attack{#} {pausetime}. *~attack.seal.cost - See seal {energy}. *~attack.seal.time- See seal {time}. *~attack.size.x - See attack{#} {width}. *~attack.size.y - See attack{#} {height}. *~attack.size.z.1 - See attack{#} {z}. *~attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. *~attack.staydown.rise.time - See staydown {rise}. *~attack.staydown.attack.time - See staydown {riseattack}. *~attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. attack11,attack12,... *~These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). *~After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. blast {x} {y} {right} {down} {damage} {block} {noflash} {pausetime} {z} *~'''This command is deprecated and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. *~An attack box which can hit bboxes. *~Unless otherwise specified, this works exactly like an 'attack' command. *~blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. shock {x} {y} {right} {down} {damage} {knockdown} {block} {noflash} {pausetime} {z} *~A shock attack box which can hit bboxes. *~Unless otherwise specified, this works exactly like an 'attack' command. *~If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. burn {x} {y} {right} {down} {damage} {knockdown} {block} {noflash} {pausetime} {z} *~A burn attack box which can hit bboxes. *~Unless otherwise specified, this works exactly like an 'attack' command. *~If this attack hits an enemy or player, they will play their BPAIN or BURN animation. freeze {x} {y} {right} {down} {damage} {time} {block} {noflash} {pausetime} {z} *~A paralyzing attack box which can hit bboxes. *~Unless otherwise specified, this works exactly like an 'attack' command. *~The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. *~{time} is measured in seconds. *~Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). steal {x} {y} {right} {down} {damage} {knockdown} {block} {noflash} {pausetime} {z} *~An attack box which can hit bboxes. *~Unless otherwise specified, this works exactly like an 'attack' command. *~If this box hits a player or enemy, it will drain life from the target and give it to the attacker. move {x} *~Starting with the next frame, the entity will move forward (x) pixels with every new frame. *~This value must be set to 0 again to stop the entity from moving any further during the animation. *~You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). *~Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. movea {a} *~Starting with the next frame, the entity will move upward (a) pixels with every new frame. *~This value must be set to 0 again to stop the entity from moving any further during the animation. *~You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). *~This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). movez {z} *~Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. *~This value must be set to 0 again to stop the entity from moving any further during the animation. *~You can use a negative value for (z) to move the entity away from the screen, towards the background. seta {a} *~Changes the entity's altitude off the ground to {a}. *~The entity will remain at this altitude until changed again with 'seta' or the animation ends. *~If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. *~ Setting a>0, allows entity to fly above holes or simply not fall to holes. platform {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} / platform {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} *~Turns an entity into a walkable platform. *~There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. *~This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the platform starts . For 1st form, {xpos} and {zpos} aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. *~{lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the platform. These numbers are how far from the {xpos} the corners are. *~{depth} is the z depth of the platform: how far it stretches from the {zpos} to the top of the screen. *~{alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. *~This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). *~If this entity moves with command or script, any entities on top of it will also move together with it. *~You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) sound {path} *~{path} points to a sound effect. The sound will be played as soon as the next frame is reached. *~You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. fshadow {int} *~This is used to set entity's shadow for the current frame. *~Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). *~This consumes more memory so use with care. shadowcoords {x} {y} *~Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. *~Obviously the entity must use 'shadow' before using this. *~This consumes more memory so use with care. itembox {x} {y} {right} {down} *~An item box which can hit bboxes. This can only be used by 'item' entities. *~{x}, {y}, {right}, and {down} work exactly like in a bbox. *~If another entity touches this itembox, the item will be picked up by that entity. *~The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate} *~This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. *~{scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. *~{scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. *~{flipx} is integer value, when set to 1, the frame will be flipped leftright. *~{flipy} is integer value, when set to 1, the frame will be flipped updown. *~{shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. *~{alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. *~{remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. *~{fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. *~{rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. *~{fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so *~This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) drawmethod scale {scalex} {scaley} *~If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. drawmethod scalex {scalex} drawmethod scaley {scalex} *~These 2 are subset of the previous scale command. drawmethod flipx {0/1} drawmethod flipy {0/1} *~ useful to flip the frame in X or Y direction (or horizontal and vertical) drawmethod shiftx {value} *~Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. drawmethod rotate {angle} *~Rotate the sprite, clockwise. drawmethod fliprotate {0/1} *~If the rotation is affected by entity direction. drawmethod fillcolor {color} *~Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. drawmethod remap {int} *~Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. drawmethod alpha {int} *~Like above, use -1 or leave alone to avoid overriding. drawmethod channel {r} {b} {b} *~When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. *~For example the code below will grand the entity 25% opacity: drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b} *~These are subset of channel. drawmethod tintmode {int} drawmethod tintcolor {color} *~These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. drawmethod clip {x} {y} {w} {h} *~This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area *~ All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. [[File:Openbor_clip.png ]] *~'''Important info:''' Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. nodrawmethod *~This command disables 'drawmethod'. *~Use this with 'drawmethod' of course. See 'drawmethod' above. hitfx {path} *~{path} should point to a .wav file. *~If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. *~Like the normal hitsfx, the higher the attack power, the slower this sound will play. hitflash {name} *~{name} is the name of an entity declared in MODELS.txt. *~If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. idle {flag} *~Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. *~For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. *~This command works from defined frame to last frame unless resetted. @cmd {functionname} {parameter} ... *~Calls a script function to be run at this frame *~Called function can be from generic functions or from animation script *~For the latter, make sure the animation script is defined before calling (see animation header above) *~Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has *~All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== grabin {type} {distance} *~If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance *~{distance} controls how far entity and opponent would be when grabbing starts. *~Use this command with non knockdown attackbox of course. forcedirection {dir} *~If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. *~Use this command with an attackbox of course. damageonlanding {value} {type} *~If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. *~Use this command with knockdown attackbox of course. dropv {height} {speedx} {speedz} *~This command controls opponent's flight path during his/her FALL animation. *~{height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. *~{speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. *~{speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. *~Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. *~Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. nokill {bool} *~ 0 - (default) The attack will kill the target. Useful to turn NOKILL off. *~ 1 - The attack won't kill the target but will leave 1 HP. stun {int} *~This command makes the attack freezes opponent for {int} seconds without remap change. *~If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. *~Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. seal {time} {energy} *~This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. *~That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. *~Usually used with slams and throws to prevent opponent to break free with special. *~Use this command with attackbox of course. However it must be declared AFTER that attackbox. forcemap {map} {time} *~This command makes the attack changes opponent's remap to {map} for {time} seconds. *~Usually used with poison, fire or elemental attacks. Just for graphical effect. *~Use this command with attackbox of course. However it must be declared AFTER that attackbox. noreflect {bi} *~This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. jugglecost {int} *~This command limits juggling ability of the attackbox. *~Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. *~This command is used in conjunction with 'jugglepoints' (see Header Data above). *~The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. OTG {bi} *~This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. guardcost {int} *~Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. DOT {Index} {Time} {Mode} {Force} {Rate} *~DOT means Damage Over Time. It works like drain feature but even better. *~Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. *~{Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. *~{Time} defines how long DOT effect active in centiseconds. *~{Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. *~{Force} defines amount of damage per tick. *~{Rate} defines delay between each tick in centisecond. staydown {rise} {riseattack} *~Gives more or less delay to opponent's rise and riseattack. *~{rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. *~{riseattack} defines how much additional time in centiseconds before opponent's next riseattack. *~Both effect are gone once opponent rises or riseattacks. *~Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt. Limitations: *~Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. *~Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). *~Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: Original player file: *~Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} *~{name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. *~{original name} is the name of the character when it doesn't have any weapons equipped. Player with weapon model: *~Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. *~You do need a name, though. And it has to match the name used in the original player's {name#} field. *~You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. *~This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. Item which gives you the weapon: *~Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. flash.txt *~A standard .txt file for an entity, but the only animation it needs is IDLE. *~It should have type none. It doesn't behave any different with any other type, though. *~This graphic plays when an attack box of any kind hits a bbox. *~The offset is the point at which the flash will be centered. *~I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. *~BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. *~This can be overridden on a per-entity basis with various commands. *~Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. data/pal.act *~This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. *~There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. *~If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. data/SPRITES/font.gif *~The most-often used font. *~Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! data/SPRITES/font2.gif *~The font used when a selection is highlighted, and for newly-added scores on the high score screen. *~Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! data/SPRITES/font3.gif *~This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. *~Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! data/SPRITES/font4.gif *~The large font used for 'game over' and 'next' screens, the timer, and a few other places. *~There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. *~Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! data/SPRITES/font5.gif, font6.gif ... *~These fonts are extra fonts and are not used anywhere by default. *~To make these, simply make font image like other font images above and name it properly. *~These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. data/SPRITES/shadow{#}.gif *~{#} is a number from 1 to 6. *~This graphic is used as a shadow with negative alpha transparency. *~You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. *~The shadows are only useful if you're not using 'gfxshadow' (see above). data/SPRITES/arrow.gif *~Normally, an arrow pointing rightward. *~When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. *~For direction left, this graphic will be flipped. data/SPRITES/arrowl.gif *~This works like the arrow.gif file, but it flashes on the left half in direction left levels. data/bgs/hiscore.gif *~A background for the high score screen. *~In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. data/scenes/gameover.txt *~This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. *~If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. data/bgs/complete.gif *~This is a .gif file which will be displayed as the background of the stage complete screen. *~If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. *~In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. data/bgs/select.gif *~Displays in the background of the player select screen. *~select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. data/bgs/unlockbg.gif *~Displays in the background of the player select screen, once you've completed the game at least once. data/bgs/logo.gif *~This is a .gif file which will be displayed when OpenBoR starts. data/scenes/logo.txt *~This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. *~What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. *~If this file isn't found, OpenBoR immediately goes to intro.txt (see below). data/scenes/intro.txt *~This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. *~Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. *~If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. data/scenes/howto.txt *~This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. *~Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. *~If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. music {path} {loop} *~{path} points to a .bor music file which will play. *~{loop} determines if the music loops. **0 = no looping. **1 = looping. *~Played music will override the previous one. animation {path} {x} {y} {skip} {noskip} *~{path} points to an animated .gif file which will be played. *~{x} and {y} are the x and y positions of the top left corner of the .gif. *~{skip} is a flag that allows players to skip current animation. Set to 1 to enable it. *~{noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. *~The size of animated gif should be same as mod's resolution (see video.txt above) *~It is possible to use smaller gif but there will be black box in unused space when scene is played silence {int} *~If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. music {path} {loop} *~{path} points to a .bor music file which will be played during this select screen. *~{loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. background {path} *~Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. *~{path} points to background graphic. *~Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. *~However in truecolor mode, any palette will do allowselect {playername1} {playername2} .... *~Defines allowed players in this select screen just for current level set. *~{playername#} is the name of player. You can define more than one but no need to repeat same one. *~Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. *~The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. load {name} *~This forces engine to load other entity into memory so the entity can be used. *~{name} is name of loaded entity. *~Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. *~Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} / background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} *~These 2 command have same effect which is create a background layer with the image at {path}. *~The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). *~The height could be any size but make sure it matches screen resolution to avoid void background areas. *~Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette *~Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work *~The graphic automatically repeats if the stage is longer than the background. *~Layers are drawn in the order they are defined; currently, up to 100 are supported. However 'background' sets the bottommost layer while 'bglayer' sets layers in front of it. *~{xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. *~{xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. *~{xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). *~{xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever *~use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don't use it on images that won't benefit from it. And don't use it for 'background' too since it's the bottommost layer. In 16/32 bit mode, pure black color will be used instead. *~{alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don't use it for background too. *~{watermode} determines water effect. Currently there are 3 modes. **0 = No water effect for this bglayer **1 = Water effect for this bglayer is on **3 = Mode 7 effect *~{amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) *~{wavelength} determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) *~{wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) *~When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} *~{beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther *~{perspective} defines z depth effect it should have **0 = No effect (default) **1 = Perspective & tile **2 = Perspective & stretch *~{bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). bgspeed {speed} {dir} *~Causes the background of the stage to scroll by automatically in horizontal direction. *~{value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. *~{dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right vbgspeed {speed} {dir} *~Causes the background of the stage to scroll by automatically in vertical direction.(4287+) *~{value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. *~{dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up *~use vbgspeed+bgspeed combo for diagonal levels water {path} {warp} *~Optional. *~{path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette *~the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. *~If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. *~If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. rock {int} *~Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. mirror {bi} *~Optional. *~Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. panel {norm} {neon} {scrn} *~{norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. *~Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette *~Beware though, if panels use different palette than background, 'palette' command (see below) won't work *~Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image *~If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! *~In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt *~In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 *~You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. *~All panels in a stage should have the same length and height. *~If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. *~Normal mode panel layers are just plain images. They have no visual effects. *~Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. *~Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. *~You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. frontpanel {path} *~{path} points to a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. *~Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette *~Beware though, if frontpanels use different palette than background, 'palette' command (see below) won't work *~frontpanels display in the order they are declared and repeat when they run out. You don't need to declare an order like with normal panels. *~frontpanel has its own scroll speed ratio which can't be changed. If you don't like it, use 'fglayer' below instead order {panel#}{panel#}{panel#}... *~Determines the order of panels in a stage. *~{panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). *~The same panel can be used more than once. *~You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef *~That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. *~If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf} *~This command allows custom loading background to be displayed while the current level are being loaded. *~{path} determines the location of used background. *~{set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. *~{bx} and {by} determines x and y coordinates of loading bar top left's location respectively. *~{bsize} determines loading bar's length. *~{tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. palette {path} {a1} {a2} {a3} {a4} {a5} {a6} *~This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background *~{path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. *~{a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. *~This transparency feature costs 384kb memory when palette is loaded so use with care. *~This command can be declared more than once if more palettes are required. cameratype {bi} *~This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) *~If set to 1, panel's height controls how far up or down camera can go (both in z and y). fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} *~This is for setting custom foreground layer in current level. *~{path} is the location relative to data folder where the graphic is *~Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette *~Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work *~{z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. *~Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in 'bglayer' above. *~Currently {watermode}, {amplitude}, {wavelength} and {wavespeed} aren't working. Still, you need to fill them if you want to set {bgspeedratio}. cameraoffset {x} {z/y} *~This command is used to control point the camera focuses on. *~Camera means view of game. You won't see any effect of this unless your levels are wide. *~Positive value for {x} shifts camera right, for {z/y} shifts camera up. *~Negative value for {x} shifts camera left, for {z/y} shifts camera down. scrollspeed {int} *~This command defines how fast screen scroll when player scroll the screen *~Default value is 1 which means screen scrolls 1 pixel per frame *~Recommended in high resolution mods ==Non-Graphics== type {type} {nospecial} {nohurt} *~Optional. *~{type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). *~Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) *~{nospecial} Can use specials during bonus levels (default 0 - yes) *~{nohurt} Can hurt other players during bonus levels (default 0 - yes) music {path} {offset} *~Optional. *~{path} points to a .bor music file which will be played during the stage. *~{offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. *~you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> bossmusic {path} {offset} *~Optional. *~{path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. *~{offset} works same way as in 'music' above. spawn1 {x} {z} {a} *~Optional. *~{x} is relative to the starting edge of the screen. {z} is relative to the stage's minimum z value. {a} is relative to the ground. *~{x} is measured from left for levels with direction right and both and it's measured from right for levels with direction left. *~Although {x} could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). *~However, it's possible to give {x} negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *~{z} could be any value but it can't put player 1 beyond maximum z value. *~Setting {a} > 0 makes player falls down on respawn. Default value for a is 300. NOTE: {a} only effect respawn not when level starts. *~If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. spawn2 {x} {z} {a} *~Optional. *~Works exactly like spawn1, except that it sets the respawn position for Player 2. spawn3 {x} {z} {a} *~Optional. *~Works exactly like spawn1, except that it sets the respawn position for Player 3. spawn4 {x} {z} {a} *~Optional. *~Works exactly like spawn1, except that it sets the respawn position for Player 4. allowselect {playername1} {playername2} .... *~Defines allowed players in this select screen just for this level. *~{playername#} is the name of player. You can define more than one but no need to repeat same one. *~Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. *~The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. direction {dir} *~Determines which direction the screen scrolls in. *~{dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. *~Screen, neon, water, etc don't work well in direction in, out, inout and outin. settime {int} *~This stage's time limit will be {int}. *~If {int} is 0, the player will have unlimited time. *~The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! *~Using 'settime 1' isn't funny. Okay, it's a little funny the first time. *~Don't forget to use 'Time' items when needed! nofadeout {bi} *~Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes notime {bi} *~Determines whether or not the player can see the game timer. noreset {int} *~Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. noslow {bi} *~Determines whether or not the game slows down after beating a boss. hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type} *~A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. *~In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. *~This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). *~{lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. *~{depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. *~{alt} is used to control the height of the hole. (4287+) *~{type} the type is a param useful for decide what type of terrain is that hole. *~As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 *~If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. *~If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. *~The default values are 240, 12, 1, 200, 287, and 45, respectively. *~{alt} {type} are optional wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type} *~Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. *~All of the field except {alt} are the same as they are in holes. *~{alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. *~{type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) *~If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. *~In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. *~{type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax} *~Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) *~{xpos} {zpos} works like wall or holes *~{xsize} defines the ramp width *~{zsize} defines the ramp size (or wide) in z axis *~{amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] endhole {bi} *~Optional. *~Determines if the rightmost edge of the stage is a pit. *~1 means yes. 0 means no. *~Don't use this if your stage scrolls left. Trust me on this one. *~This command is outdated and only left for backward compatibility sake. Use 'hole' above instead blocked {bi} *~Optional. *~Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. *~Entities who hit the wall will stop moving. *~This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. *~If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). *~This command is outdated and only left for backward compatibility sake. Use 'wall' above instead gravity {value} *~This sets gravity or falling speed in the level. *~It should use negative value. Defaults to -10 *~Setting -5 makes characters fall like in water. maxfallspeed {value} *~This sets maximum falling speed in the level. *~It should use negative value. Defaults to -60 *~Setting -20 makes characters fall like in water. maxtossspeed {value} *~This sets maximum jumpheight in the level. *~It should use positive value. Defaults to 1000 stagenumber {int} *~Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). *~Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. noscreenshot {bi} *~If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. *~Players can still access options menu while pausing by screenshot button with this command set 1. nopause {bi} *~If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though setweap {int} *~Sets starting weapon in this level for players based on weapon's number. *~Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). *~Make sure the weapon is available before setting this. levelscript {path} *~This command defines which script is run when this level is played *~It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== spawn {name} {bi} *~{name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. *~{bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. *~{name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. 2pspawn *~If this is declared, the entity is only spawned if there are 2 players playing. 3pspawn *~If this is declared, the entity is only spawned if there are 3 players playing. 4pspawn *~If this is declared, the entity is only spawned if there are 4 players playing. alias {name} *~The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. *~The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. map {pal} *~{pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. health {int} *~{int} is a health value which will be used instead of the entity's normal health. 2phealth {int} *~{int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. 3phealth {int} *~{int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. 4phealth {int} *~{int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. mp {int} *~For items spawned in a stage. *~When a player picks this item up, they'll regain {int} MP instead of it's normal value. dying {remap} {health1} {health2} *~If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. *~If their health drops to or below {health2}, they flash even faster. item {name} {bi} *~Optional. *~When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. *~{bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. *~You can't make an entity drop multiple items. itemhealth {int} *~Optional. *~Changes the health of a dropped entity to {int} itemmap {int} *~Optional. *~Changes the pallete of a dropped entity to {int} itemalias {name} *~Optional. *~Changes the name of a dropped entity to {name} 2pitem {name} {bi} *~Optional. *~Works just like 'item', except that this will only be spawned if there are 2 people playing. 3pitem {name} {bi} *~Optional. *~Works just like 'item', except that this will only be spawned if there are 3 people playing. 4pitem {name} {bi} *~Optional. *~Works just like 'item', except that this will only be spawned if there are 4 people playing. boss {bi} *~Optional. *~If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) flip {bi} *~Optional. *~If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. *~Can also be used for entities with subtype arrow to make them fly from left to right. coords {x} {z} {a} *~Determines the x, z, and a positions on the screen where the entity will spawn. *~{x} is relative to the screen's current position, NOT the actual position in terms of the level itself. *~{z} is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *~{a} is how high off the ground the entity will spawn. *~If {x} is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. *~If {x} is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. *~In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. *~Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. *~Bikers should normally be spawned further out than other enemies. You'll probably want around 400 or -80 (But not more than -200 or 520, or they'll die). aggression {value} *~For enemy spawns. *~Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. min_noatk_chance {float} *~Determines the minimal chance of an enemy attack. max_noatk_chance {float} *~Determines the max chance of an enemy attack. *~if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> noatk_duration {float} *~noatk_duration affects how long the no attack period should last in seconds. *~Usually you don't need to change that (0.5-0.75 should be fine). weapon {name} {bi} Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. *~If enemy is knocked down or dies, the weapon will be dropped. *~{bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. *~Make sure the weapon is available before setting this. spawnscript {path} *~This command defines which script to be run right after entity is spawned *~Can be declared multiple times *~In multiple spawnscripts case, script will be run from the 1st to the last at {pos} *~For an entity to be spawned, the player must have scrolled to {pos} in the level. *~{pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. *~This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== wait *~This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. *~Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. *~In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. group {min} {max} *~Also not an entity spawn, also should be followed by 'at'. *~Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. *~Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. *~'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. *~This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. blockade {pos} *~Optional. Used in direction both levels. *~{pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. *~This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. *~It must be followed by 'at'. setpalette {palette} *~Change palette in use to other palette which is loaded by 'palette' (see above). *~{palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. *~Setting this to 0 or -1, reveerts palette to default palette. *~Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. shadowcolor {R_G_B} *~This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). *~{index} refers to current level palette's index. *~Setting {R_G_B} to -1 turns gfxshadow off. *~Setting {R_G_B} to -2 turns off fill color gfxshadow. *~Example of {R_G_B} format is: 0_0_255 for blue color. *~Must be followed by 'at'. shadowalpha {index} *~This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). *~In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. *~{index} refers to any alpha blending type i.e 1-6. *~Setting {index} to -1 turns gfxshadow alpha off. *~Must be followed by 'at'. shadowopacity {index} *~This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). *~{index} refers to opacity value i.e 0-255. *~Setting {index} to -1 turns gfxshadow to 0. *~Setting {index} to -2 turns gfxshadow alpha off. *~Must be followed by 'at'. light {x} {z} *~This command changes light direction to {x} {z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). *~If {x} is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *~{z} can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. *~Must be followed by 'at'. load {name} {bi} *~Used to load a model whose name is {name} in current level. *~{bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. *~This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. *~Don't forget to load {name} with 'know' in models.txt! *~Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. scrollz {min} {max} *~Used to set minimum and maximum limit for scrolling in z axis. *~Obviously {min} is the minimum limit and {max} is the maximum limit. *~This command only works in levels with direction left/right/both/leftright or rightleft. *~Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. music {path} {offset} *~Changes current music with this one at specified scrollpos. The change will occur instantly. *~If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). *~It works exactly like 'music' above (see Level Designs above). musicfade {float} *~When music changes, this command determines fading out speed of previous music. *~Higher value makes fading out faster while lower value makes fading out slower. *~Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. ---- =Music Files= Recomendations: *~Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. *~Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. How to Convert: *~You'll need a program called WAV2BOR.exe and music in .wav format. *~The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. *~NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. *~Also, stereo is only supported in OpenBoR v3.0 and up. *~Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. *~Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ *~{wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= data/sounds/beat1.wav *~Played when an attack hits an entity's bbox. *~Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. data/sounds/fall.wav *~Played when an entity hits the floor after being knocked down. data/sounds/get.wav *~Played when a player picks up an item. data/sounds/money.wav *~Played when a player grabs a score item. data/sounds/jump.wav *~Played when someone jumps. data/sounds/indirect.wav *~Played when an entity hits other entities while being thrown or blasted. data/sounds/punch.wav *~Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. data/sounds/1up.wav *~Played when the player gets a 1-up. data/sounds/go.wav *~Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. data/sounds/timeover.wav *~Played if the timer hits zero. Also played if all credits are lost. data/sounds/beep.wav *~Played in menus (not in game) when you move up or down. data/sounds/beep2.wav *~Played in menus (not in game) when you select an option. data/sounds/bike.wav *~Required if you have bikers. Plays for bikers, of course. data/sounds/block.wav *~Optional. Plays when an entity blocks an attack. data/sounds/pause.wav *~Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== projectile {relative} {name} {x} {z} {y} {direction} {ptype} {type} {map} *~ Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. *~ {relative} - Affects all other settings. See bellow *~ {name} - name of the spawned position, from models.txt *~ {x} - X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value *~ {z} - Z spawn position, defaults to 0. Accept decimals. *~ {y} - Y spawn position, defaults to 0. Accept decimals. *~ {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. *~{ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. *~{type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 *~{map} - map of the spawned entity, defaults to 0 ==Predefined Script Main Functions== *void main() {} ** This is the main function for every script. main() is the main caller *void ondestroy() {} **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example *void oncreate() {} **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. endlevel.c *~Any level ends. join#.c *~Corresponding player# (1-4) joins a game in progress. key#.c *~Corresponding player# (1-4) presses or releases a key. keyall.c *~Any player presses or releases a key. *~player: Player index (0-3). level.c *~Any level begins. pdie#.c *~Corresponding player# (1-4) dies. respawn#.c *~Corresponding player# (1-4) respawns after death. score#.c *~Score changes for corresponding player# (1-4). timetick.c *~Each tick of the game timer. *~time: Current time value. update.c *~Engine starts update cycle. updated.c *~Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. keyscript# *~Corresponding player# (1-4) presses or releases a key during this level. *~player: Player index (0-3). spawnscript *~Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. *~self: Caller. updatescript *~Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' *~This command defines which animation script to call functions from *~At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' *~This command defines which script is run when entity successfully blocked an attackdidhitscript {path} *~This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' *~Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' *~This command defines which keyscript is run when entity is active *~Only works on player type *~Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' *~This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' *~This command defines which script is run when entity is blocked by ceiling or IOW hitting head *~Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' *~Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' *~This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' *~This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' *~This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' *~Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' *~This command defines which script is run when entity dies *~Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' *~Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' *~This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' *~This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' *~This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' *~This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' *~This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' *~This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' *~Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' *~This command defines which script is run when entity is spawned and respawned (for players) *~If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' *~this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' *~This command defines which update script is run when entity is active *~Update script is script which is run every engine cycle '''takedamagescript {path}''' *~This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. *~This script is also run on final blows '''thinkscript {path}''' *~This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: *~Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. *~#include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. *~String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". *~Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' *~size is the initial size of array '''size(array)''' *~get the array size *~from r4183+ it retrieve literal array size too '''get(array,index)''' *~get the value in the index '''set(array,index,value)''' *~set the value in the index '''delete(array, index)''' *~delete the value in the index and resize the array *~dynamically remove an array element *~you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' *~add an element in the index and resize the array (+1) *~you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' *~move the pointer from current literal position to next position '''previous(array)''' *~move the pointer from current literal position to previous position '''reset(array)''' *~reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' *~in literal arrays, it retrieve the value in the current position '''key(array)''' *~in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' *~in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' *~in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' *~free an allocated array *~you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' *~path is the string path of a file, ex.: "data/scripts/file.txt" *~location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path *~it returns filestreamindex '''closefilestream(filestreamindex)''' *~close a opened file handler '''getfilestreamline(filestreamindex)''' *~it returns the string line in current position of the indexed opened file *~filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' *~it returns the value from file, at the position *~filestreamindex is the indexed opened file *~argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); *~type: this is the argument type. Types are: "int", "float", "string", "byte" *~if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' *~increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' *~it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' *~it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' *~it writes a value in filestreamindex file in the buffer *~value is the string or number that you want to write *~write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value *~value_type: optional, if is "byte" you can write a byte value *~examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' *~it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' *~it saves buffer to file *~file: file handler *~filename: filename string *~pathname: optional, if set use pathname otherwise use saves openbor path *~type: optional, is set "byte" it writes a byte (no newline at EOF) *~examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' *~Test if a ScriptVariant is an empty value. *~Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' *~Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' *~Return a global variant by name. If the value is not found, will return an empty value. *~See 'global variants'. '''setglobalvar(varname, value)''' *~Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. *~Return 1 if succeeded, 0 if failed. *~See 'global variants'. *~Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' *~Return a local variant by name. If the value is not found, will return an empty value. *~See 'local variants'. '''setlocalvar(varname, value)''' *~Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. *~Return 1 if succeeded, 0 if failed. *~See 'local variants'. *~Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' *~Clear up all global variants. *~Return: none *~You can use it when a level starts or ends to save memory. '''clearlocalvar()''' *~Clear up local variants. Only affect current script, though. *~Return: none '''getindexedvar(int index)''' *~Return a indexed global variant. '''setindexedvar(int index, value)''' *~Give value to a indexed global variant. '''getscriptvar(int index)''' *~Return a indexed script variant. '''setscriptvar(int index, value)''' *~Give value to a indexed script variant. '''getentityvar(entity, int index)''' *~Return a indexed entity variant. '''setentityvar(entity, int index, value)''' *~Give value to a indexed entity variant. '''openborvariant(varname)''' *~Return a openbor variant by name. *~Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (deprecated) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - deprecated. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' *~retrieve a random number ±X. '''srand(seed)''' *~set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' *~Draw the text in (x, y) of the screen, with font specified. *~This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). *~layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' *~Get a player's property by name. *~'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. *~'propname' is the property's name. *~'value' is new value you want to set. *~Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 *~Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' *~Just like a jump, 'toss' the entity to the air. *~'entity' is the handle of that entity. *~'height' is the jump height. *~'speedx' is the speed in x direction. *~'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' *~Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. *~'propname' is the property's name. Check spawn command in level's .txt. *~'values' is new value. *~Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' *~Clear up the global spawn entry. '''spawn()''' *~Use the global spawn entry to spawn an entity. *~Return the entity. '''openborconstant(name)''' *~Get a constant or system value by name. *~Return the value or just an empty variant if the name is not supported. Names *~''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. *~Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" *~These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" *~These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' *~Check if a key is pressed by the player. *~'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. *~'newkey?', 0 if the keys are not new. *~key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" *~Any combination is allow, but no reason to use "anybutton" with others. *~Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' *~Play a bor music. *~'name' is the path. *~'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' *~Play a defined sound sample. *~'sample' is a sample constant (see openborconstant()). *~'priority' is the playing priority. *~'lvolume' is left volume. *~'rvolume' is right volume. *~'speed' is the play speed. *~'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' *~Change current palette to specified one. *~'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' *~Kill the entity. *~'entity' is the entity you want to kill. *~This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' *~Damage the entity. *~'entity' is the entity you want to damage. *~'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. *~'force' is the attack force. default to 1. *~'drop' is whether the attack knocks down the entity. *~'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' *~Returns handle of the nearest hostile entity. *~'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. *~animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''drawbox(x,y,width,height,z,color,alpha)''' *~draw a filled box with specified position and size. *~x,y: position values on screen *~width,height: size values. *~z: depth value, similar to setlayer command or entities, check it for details. *~color: color index in palette, check you palette. *~alpha: alpha blending effect from 1 to 6, this parameter is optional. *~return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' *~draw a line from (x1, y1) to (x2, y2) *~x1, y1: position values of the start point. *~x2, y2: position values of the end point. *~z: depth value, similar to setlayer command or entities, check it for details. *~color: color index in palette, check you palette. *~alpha: alpha blending effect from 1 to 6, this parameter is optional. *~return: none '''drawdot(x, y, z,color,alpha)''' *~draw a dot at (x, y) *~x, y: position values of the dot. *~z: depth value, similar to setlayer command or entities, check it for details. *~color: color index in palette, check you palette. *~alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' *~the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). *~ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. *~some devices read the color from left to right and the others on the contrary. *~for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. *~To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' *~Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' *~Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' *~Draw current screen. *~x, y: position values of the coordination. *~z: depth value, similar to setlayer command or entities, check it for details. *~color: color index in palette, check you palette. *~alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' *~Go to branch by name. Branches is defined in levels.txt, check the manual for details. *~name: the branch name, must be those defined in levels.txt *~immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' *~Bind entity to target, so the target moves, the entity moves. *~x, z, a: relative to target. *~direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left *~bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. *~sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. *~To unbind a entity, use bindentity(entity, NULL()); *~Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. *~Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' *~Change light direction for gfxshadow. *~x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. *~Give 256 or -256 to z will make the shadow as long as its owner. *~Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' *~Change gfxshadow color. *~Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' *~Change a property value of current level, this function is not quite completed. *~name can be: *~"rock", the given value must be an interger value or numeric value that can be converted to integer value. The rule is same as rock command in level file, check the manual for details. '''loadmodel(name)''' *~"Load" a model that is currently set as "know" in models.txt. *~"name" is the model's name. '''loadsprite(path)''' *~Load a single sprite from the path specified and return the handle for later use. *~You can free the sprite by calling script function free. *~Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. *~Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. *~Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' *~Draw a sprite. *~Sprite must be a valid handle. *~x, y are the draw position. *~z is depth, sprite with a greater z value will appear above those with smaller z values. *~If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. *~See function setdrawmethod if you want to use special effects for the sprite. *~Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' *~Draw a sprite to a screen. *~sprite must be a valid handle. *~screen must be a valid handle returned by allocscreen. *~x, y are draw position. *~See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' *~Set drawmethod for an entity or define a global drawmethod for other script functions. *~entity must be a valid entity handle or an empty value. *~All other parameters are optional. *~flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. *~scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 *~scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 *~flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. *~flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. *~shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. *~alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. *~colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. *~fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. *~rotate is the rotate angle(clockwise), the range is from 0 to 359. *~rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. *~transparencybg(screen only) means whether the screen will use transparency colour. *~Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). *~Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). *~Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' *~Change drawmethod for an entity or define a global drawmethod for other script functions. *~alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. *~amplitude, // Sets the amplitude of sine wave for water effect *~beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther *~centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. *~centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. *~channelb, // Defines the value for the B (blue) channel *~channelg, // Defines the value for the G (green) channel *~channelr, // Defines the value for the R (red) channel *~clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. *~cliph, // Defines the width of the cropped area (horizontal) *~clipw, // Defines the start point in x axis (horizontal) *~clipx, // Defines the start point in y axis (vertical) *~clipy, // Defines the height of the cropped area *~enabled, // Redundant - both do the same thing. Use enabled. *~endsize, // Sets size multiplier of upper border of Water mode *~fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. *~flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. *~fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so *~flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. *~flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. *~perspective, // Defines z depth effect it should have (Water mode) *~remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. *~reset, // Resets all attributes to their default values. *~rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. *~scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 *~scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 *~shiftx, // defines how the sprite leans, like lightx in gfxshadow feature *~table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. *~tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode *~tintmode, // Defines the tintmode *~transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. *~watermode, // Determines water effect. Currently there are 3 modes. *~wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) *~wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) *~wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. *~xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever *~xspan, // For background layers, controls x spacing. See xspan. *~yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever *~yspan, // For background layers, controls y spacing. See zspan. *~Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). *~Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). *~Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' *~Play a gif file as a cut scene, you can call it in game. *~path, the gif file path, like first parameter of command animation in scene txt. *~x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. *~noskip, when set to 1, you can't press button to skip it. *~Notice: path is required. All other parameters are optional, and default value is 0. *~Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' *~Play a webm file as a cut scene, you can call it in game. *~path, the gif file path, like first parameter of command animation in scene txt. *~noskip, when set to 1, you can't press button to skip it. *~Notice: path is required. All other parameters are optional, and default value is 0. *~Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' *~Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. *~entity - animation owner. Must be a valid entity handle. Required. *~target - must be a valid entity handle. Required. *~animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' *~This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' *~This method allow the entity to do an attack, not just give it attack animation. *~anim - Optional. It stands for animation number, can be got by openborconstant. *~resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. *~Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' *~it works like performattack() but just you play an animation without animation loop. *~This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' *~This method change the entity back to idle status. *~anim - same as above. Optional. You probably will use idle animation, but that is up to you. *~resetable - same as above. Optional. *~stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. *~Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. *~Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' *~Return entity by index. *~If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. *~The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") *~Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. *~MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' *~This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. *~pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path *~filename: that you want to read/save *~value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' *~use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' *~Get an entity's property by name. *~'entity' is the handle of that entity. *~'propname' is the property's name. *~'value' is new value you want to set. *~Property names: **"a" - Altitude (deprecated) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' *~loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' *~gets the info from *.sav file loaded by loadgamefile(). *~if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). *~set_index is the index of your set. from 0 to ... X *~prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' *~set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. *~Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' *~it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' *~it closes the engine. '''gotomainmenu(flag)''' *~to go to main menu *~flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 *~flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' *~it allocs a script in memory. *~useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' *~it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' *~it compile a script on fly '''executescript(handle)''' *~it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' *~search the first match in a string. *~params are complete string and substring to search in complete string. *~it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' *~like strinfirst() but returns the last substring match. *~that is the func search in the string from right (not from left) '''strleft(string, index)''' *~it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' *~like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' *~it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' *~it returns the string width in pixels depending by the font. *~if the width of the character is 6 pixels and the string is "HELLO" *~strwidth("HELLO") will returns 6x5 = 30 (30 pixels) *~useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' *~it returns 1 if there's hole here, otherwise it returns 0 *~y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' *~it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 *~y is optional *~you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' *~it returns the height of wall from 0 (not wall or height 0) to... X height *~y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' *~it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 *~y is optional *~you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' *~it returns the base height in X,Z coords. *~if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' *~it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 *~you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' *~it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' *~it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' *~it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' *~It generates an inclined terrain *~map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") *~rx: it generates basemap from coord X *~rz: it generates basemap from coord Z *~x_size: it generates basemap from coord X to x+x_size *~z_size: it generates basemap from coord Z to z+z_size *~min_y: is the minimum height *~max_y: is the maxmimum height *~you can invert min_y and max_y too! *~x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' *~Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. *~name: pathname *~loop: toggle 1 or 0. 1 for loop music *~offset: start music offset '''fademusic(fade, name, loop, offset)''' *~With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. *~fade volume (0 ~ 128) *~name: pathname *~loop: toggle 1 or 0. 1 for loop music *~offset: start music offset '''setmusicvolume(left, right)''' *~left: stereo left volume (0 ~ 128) *~right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' *~{ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' *~toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' *~it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' *~it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' *~it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' *~returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' *~query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' *~id: loaded sample *~priority: to play channels with lowest current priority first. default -1 *~lvolume: left volume *~rvolume: right volume *~speed: sound speed (integer): from 0 to.. x *~loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' *~filename: filename to load *~log: if 1 it writes a log '''unloadsample(id)''' *~id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! *~Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! *~OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! *~Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! *~You probably found a bug or something has been changed in the engine. *~In either case, report that to LavaLit.com <http://www.lavalit.com/> *~Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' *~Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? *~Something is wrong with the file at {path}. Some possible known causes: *~One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. *~Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. *~The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: *~{path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. *~{path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' *~The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. *~Check {com}'s spelling. For instance, it's colourselect, not colorselect. *~Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) *~This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. *~To fix this, just go to the last line in the offending .txt file(s) and press enter once. *~This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h *~Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= Outside the Box: *~OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. *~Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... *~Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. *~Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. *~Enemies can drop other enemies. That means you can create enemies with second forms. *~An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. Cutscenes: *~There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. *~These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt *~These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt Score: *~When you hit an enemy, you get 5x the attack's damage in points. *~THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). *~You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. *~You get a one-up every 50,000 points. Time: *~Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. *~To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. Projectiles: *~Knives fly straight forward. They can fly over pits unless they are on the ground. *~Stars can only be thrown during jumps. Three fly out at downward angles. *~Bombs fly in an arc. They can be thrown over pits. Player Swapping: *~'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. *~You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. Other notes: *~Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. Fun: *~Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. *~The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... *~There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? *~It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. Limits : Maximum number of: *~Individual Sprites: NA** *~Animations: NA** *~Total Frames: NA** *~Frames per animation: NA** *~Models: NA** *~Entities in play: NA** *~Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. *~Panel Use: 100 - This is the number of panel definitions you may use in a single level. *~Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. *~Remaps: 30 - Total number of color maps (including the default) available for each model. *~Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. *~Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. *~Hole: 40 - Number of uses you have for the Hole command per level. *~Levels: 100 *~Difficulty levels: 10 *~Sound effects: 512 *~Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. *~Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). *~Health: 2,147,483,647 - Maximum possible health for a single entity. *~MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" *~It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" *~HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? *~Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? *~That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? *~That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? *~I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! *~The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! *~This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? *~Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? *~BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. *~OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. *~BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. *~HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. *~[[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? *~OpenBoR is by far the best choice as of this moment. Each version has its advantage though: *~The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. *~OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. *~BoRHed also adds new features, but an entirely different set. *~HoR was designed for overhead/sideview shooters, so that's something of a different situation. *~[[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? *~You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? *~When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. *~Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. *~Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) *~Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. *~Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. *~If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? *~Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. *~Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? *~Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? *~Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. Bloodbane: *Manual updater. ''OpenBoR Manual contributions'': bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. Currently updated by O Ilusionista ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 1ce063766586d5cfdc362a15acfc4876a1ffd0ca Hardware variations 0 1315 2579 2023-03-03T01:03:42Z Unknown user 0 Created page with "The Dreamcast had three major hardware variations, usually referred to as v0, v1, or v2 consoles. U.S. and PAL consoles can be identified easily through the sticker on the bot..." wikitext text/x-wiki The Dreamcast had three major hardware variations, usually referred to as v0, v1, or v2 consoles. U.S. and PAL consoles can be identified easily through the sticker on the bottom of the console, which will have the version number in a circle printed on it. v0 consoles are known for their heatpipe cooling system, which can be identified by the metal fan shroud from the outside of the console. v1 consoles use 5V levels on the G1 bus, creating a compatibility issue with G1 devices designed for 3.3V levels. v0 units are more common in Japan. These models have a separate GD-ROM daughterboard. v1 consoles are the most common in the United States and Europe, and are the most compatible with Dreamcast mods. These consoles have plastic fan shrouds, a 3.3V level G1 bus, and a separate GD-ROM daughterboard. v2 consoles are less common, and have the GD-ROM functionality built directly into the motherboard, so the GD-ROM cannot be replaced with an [[Optical drive replacements|optical drive emulator]] device. They have plastic fan shrouds and 3.3V level G1 bus. Some later v2 consoles came fitted with firmware v1.022, which disables [[MIL-CD]] booting, so CD-based software like homebrew and indie games cannot be used without a [[BIOS modification]]. An unofficial variation of the console is the portable Chinese [[Treamcast]]. bb32abf36e9abbf7bc229c8f56e2968892b1906d File:Tcbottom.jpg 6 1316 2580 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tcbottom}} |date=2004-07-19 12:07:02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a3c9fb0c8f8f54575034c2c065f918109545649f File:Tcfront.jpg 6 1317 2581 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tcfront}} |date=2004-07-19 12:06:46 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} b8470c48533efac17d84015308d06330184cf050 File:Tcleft.jpg 6 1318 2582 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tcleft}} |date=2004-07-19 12:06:38 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 691a637915d4786d14cd3ffc16d29ddaf16eac05 File:Tclidopen.jpg 6 1319 2583 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tclidopen}} |date=2004-07-19 12:07:17 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2d0d0477df55c6dd437cbc48b4ca05e66d3e3c14 File:Tcopen.jpg 6 1320 2584 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tcopen}} |date=2004-07-19 12:07:12 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} bbdf1aaca444ba9cf114334f9a92c298379795fe File:Tcright.jpg 6 1321 2585 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tcright}} |date=2004-07-19 12:06:54 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a6df7befa0b33d4a7dbbd0d44b70605990f0815e File:Tctop.jpg 6 1322 2586 2023-03-03T01:06:48Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Tctop}} |date=2004-07-19 12:06:28 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ab46072ddbbfa0a8fc52896c44b24f1e8d82ab0c File:Treamcast2pin.jpg 6 1323 2587 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcast2pin}} |date=2004-07-19 12:06:08 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2630a278ff3a3fe76f548b61a787a23fea318f80 File:Treamcastbag.jpg 6 1324 2588 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastbag}} |date=2004-07-19 12:04:36 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 1e87c30bc82cc94e7be9c4cfaa0c4ea3f80744b5 File:Treamcastbagempty.jpg 6 1325 2589 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastbagempty}} |date=2004-07-19 12:06:15 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} c75329431964e127cc6c318f7d61a7a9e101927c File:Treamcastbagopen.jpg 6 1326 2590 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastbagopen}} |date=2004-07-19 12:04:47 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} dbf21a49af5eb816b5a659d32336612c9d993b6e File:Treamcastcar.jpg 6 1327 2591 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastcar}} |date=2004-07-19 12:05:54 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 6ebcfc2d6ee3f9f942fa366a6d3a61c9466e5292 File:Treamcastjoy.jpg 6 1328 2592 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastjoy}} |date=2004-07-19 12:04:59 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 19a8654629ddbaf324d50bcc3ce07713fb6d39ee File:Treamcastplayer.jpg 6 1329 2593 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastplayer}} |date=2004-07-19 12:05:41 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f5c12b970e291d3e12fb542da18139601a2d7bd7 File:Treamcastpower.jpg 6 1330 2594 2023-03-03T01:06:49Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Treamcastpower}} |date=2004-07-19 12:05:15 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 3bedbd07e3312e5f21249551ac7e94b4b3533ebe Treamcast 0 79 2595 240 2023-03-03T01:07:05Z Unknown user 0 wikitext text/x-wiki '''Treamcast''' was a Chinese company creating unlicensed aftermarket Dreamcast products, including the "Treamcast" console, a rebranded Dreamcast console with a built-in portable screen. The console was not technically a clone since it used mostly salvaged Dreamcast parts with a new case featuring a built-in screen. The console featured a hacked [[BIOS]] with Chinese language support. Treamcast also made several accessories and peripherals for the Dreamcast. Below is a December 4, 2004 account of purchasing the Treamcast console from wraggster: ==Buying the Treamcast== I live in England so buying from Hong Kong was a risky move for me but I decided to take the risk, I had already bought several items from Success HK and was quite happy to go ahead with buying one off them, the price for the Treamcast was $173 which is around £85 in my money so a very good price, infact the best i could find. The cost of delivery was in my opinion decent, $47 dollars (£23) for UPS to deliver it so not too bad so far and the 3/4 day delivery time made me very happy. Sad for me but customs got a hold of the parcel and i got charged £31 extra for taxes/handling so the first downer so far but overall the price was still decent and cheaper than anyone else. '''Important Update''' A company in the UK called [http://www.gbax.com/ GBAX] also sell the Treamcast for a great price of £129 which is fantastic and they have a great name too, for those of you who are after a Treamcast. The Treamcast was wrapped in a good sturdy box and inside lots of bubble wrap so in case of heavy handling it should be fine. '''The Treamcast (pictures and small descriptions)''' '''Here's the picture of the unopened Treamcast Bag.''' [[Image:treamcastbag.jpg]] As you can see the bag is quite compact but fits everything in quite well and is made rather well. '''Treamcast Bag Opened''' [[Image:treamcastbagopen.jpg]] As you can see everything is all snugly fitted in, let's see what we have. '''Treamcast Joypad''' [[Image:treamcastjoy.jpg]] The joypad looks like a white version of the old Sega Megadrive joypads, complete with turbo buttons. '''Power Supply''' [[Image:treamcastpower.jpg]] The power supply can be used on 110/220v supplys. '''VCD/MP3 Player''' [[Image:treamcastplayer.jpg]] Video CD and MP3 Player with remote control. '''Car adapter''' [[Image:treamcastcar.jpg]] Well made adapter but shortish lead. '''2 Pin Travel Adapter''' [[Image:treamcast2pin.jpg]] 2 Pin travel adapter. Nice, eh? :) '''Empty Treamcast Bag''' [[Image:treamcastbagempty.jpg]] The Treamcast bag itself has the main compartment which the Treamcast fits in with 2 smaller side compartments for the other items and on the left hand side of the picture it has sleeves for games/cds to sit in. ==Pictures of the Treamcast== '''Picture of the Top''' [[Image:tctop.jpg]] Nothing much to see here. '''Left Side Photo''' [[Image:tcleft.jpg]] On the left you can see the Colour and brightness controls. '''Full Frontal''' [[Image:tcfront.jpg]] Similiar in looks to a normal Dreamcast but with an headphone port. '''Right Side photo''' [[Image:tcright.jpg]] Volume Control, Speaker (one on both sides) but an empty modem slot. '''Photo of the Bottom''' [[Image:tcbottom.jpg]] Nothing of interest there. '''Treamcast with Lid Open''' [[Image:tcopen.jpg]] Totally flat design compared to the normal Dreamcast. '''Lid Open Picture''' [[Image:tclidopen.jpg]] There you go, that's enough pictures, let's get down to buisness, onto the review. ==The Review Itself== '''The accessories bit ''' When opening the package I was impressed with the bag and the quality of it, everything was very well packaged inside. First thing I had to check was the power supply adapter and thankfully it works in the UK with the addition of a Shaver adapter (around 50p). I got the system set up very quickly and then tried the power button, the power adapter itself had a fan built into it which wasn't too noisy although you could hear it. '''The Joypad''' The Treamcast joypad is a throwback to the old Sega Megadrive/Genesis style joypad and while it was ok to use I did find the directional control a bit clicky, so for me the original joypads are much more preferable and to that there's no place where to put your [[VMU]]. '''The VCD/MP3 Player''' Well, I read the packaging and it said it also supported S-VCDs too so I was quite excited to try this, but it didn't work, the player kept on saying the controller (the IR receiver) wasn't there, so thats one bad tick from me and I will be emailing the supplier for a new Set ASAP, the remote control was ok and had the words Dream Movie on it and was good enough for the purpose, but until I can get a hold of a replacement unit, I cant say if it does play VCD 2.0/MP3/ SVCD disks. I would presume it plays VCD/MP3, the SVCD is doubtful, but let's wait and see. '''The Treamcast''' The Treamcast sounds just like the Original Dreamcast when using either CDs or GD Roms, it played everything I threw at it and that includes Commercial Games, Homebrew, Emulators, MP3 Players. The reading time was no less or more than on an original Dreamcast. The speakers played perfect throughout no crackling whatsoever, I was also surprised to see an AV port on the back of the Treamcast, so if you want, you can connect the Treamcast to your fancy big screen, but that is just an option. '''The Screen''' The main reason to purchase the Treamcast was the reason to use it in a car or anywhere that has a power supply. (For example: When you are on holiday) The TFT screen has a great picture and even on fast games it played very well, the one area i felt that it struggled on was games that were very Dark. It did play them but certainly not as good as i would have liked. '''Treamcast Good or Bad''' I'll do a Pro/Con thing then give my final viewpoint. '''Pros ''' *Portable Dreamcast (that itself is the great thing) *Playability in Car. *Price *TFT Screen (great for bright/normal light games) *Accesories/Bag/Adapters *Good Sturdy Design '''Cons''' *Clicky Joypads (might be a personal preference) and nowhere to install the VMU. *VCD/MP3/SVCD Player (didnt work) *TFT Screen (very dark games it struggles on) *Customs charges(bleh) ==Conclusion== '''Would I recommend one?''' The answer is a massive yes, apart from the commercial games there are loads of great emulators that you can play on this machine, as well as VCD players, MP3 Players and a multitude of Homebrew game ports, applications and self written games & demos. The problems are far outweighed by the good things and I'm looking forward to giving my Treamcast a lot of quality time. One thing I'll say is, that it is important who you buy from, I got mine from [http://tinyurl.com/yropq Success HK] and they have a good reputation but others do not, so be careful. '''Important Update''' A company in the UK called [http://www.gbax.com GBAX] also sell the Treamcast for a great price of £129 which is fantastic and they have a great name too, for those of you who are after a Treamcast. Thanks for reading -wraggster b54158131dbc0ebb2ebfdbb83397f39ea523a654 2596 2595 2023-03-03T01:16:46Z Unknown user 0 wikitext text/x-wiki '''Treamcast''' was a Chinese company creating unlicensed aftermarket Dreamcast products, including the "Treamcast" console, a rebranded Dreamcast console with a built-in portable TFT screen. The TFT used the composite video output of the Dreamcast. The console was not technically a clone since it used mostly salvaged Dreamcast parts with a new case featuring a built-in screen. The console featured a hacked [[BIOS]] with Chinese language support. Treamcast also made several accessories and peripherals for the Dreamcast. The console existed in white, black, and [https://twitter.com/A3rgan/status/1534228375539269633 widescreen] variants. Below is a December 4, 2004 account of purchasing the Treamcast console from wraggster: ==Buying the Treamcast== I live in England so buying from Hong Kong was a risky move for me but I decided to take the risk, I had already bought several items from Success HK and was quite happy to go ahead with buying one off them, the price for the Treamcast was $173 which is around £85 in my money so a very good price, infact the best i could find. The cost of delivery was in my opinion decent, $47 dollars (£23) for UPS to deliver it so not too bad so far and the 3/4 day delivery time made me very happy. Sad for me but customs got a hold of the parcel and i got charged £31 extra for taxes/handling so the first downer so far but overall the price was still decent and cheaper than anyone else. '''Important Update''' A company in the UK called [http://www.gbax.com/ GBAX] also sell the Treamcast for a great price of £129 which is fantastic and they have a great name too, for those of you who are after a Treamcast. The Treamcast was wrapped in a good sturdy box and inside lots of bubble wrap so in case of heavy handling it should be fine. '''The Treamcast (pictures and small descriptions)''' '''Here's the picture of the unopened Treamcast Bag.''' [[Image:treamcastbag.jpg]] As you can see the bag is quite compact but fits everything in quite well and is made rather well. '''Treamcast Bag Opened''' [[Image:treamcastbagopen.jpg]] As you can see everything is all snugly fitted in, let's see what we have. '''Treamcast Joypad''' [[Image:treamcastjoy.jpg]] The joypad looks like a white version of the old Sega Megadrive joypads, complete with turbo buttons. '''Power Supply''' [[Image:treamcastpower.jpg]] The power supply can be used on 110/220v supplys. '''VCD/MP3 Player''' [[Image:treamcastplayer.jpg]] Video CD and MP3 Player with remote control. '''Car adapter''' [[Image:treamcastcar.jpg]] Well made adapter but shortish lead. '''2 Pin Travel Adapter''' [[Image:treamcast2pin.jpg]] 2 Pin travel adapter. Nice, eh? :) '''Empty Treamcast Bag''' [[Image:treamcastbagempty.jpg]] The Treamcast bag itself has the main compartment which the Treamcast fits in with 2 smaller side compartments for the other items and on the left hand side of the picture it has sleeves for games/cds to sit in. ==Pictures of the Treamcast== '''Picture of the Top''' [[Image:tctop.jpg]] Nothing much to see here. '''Left Side Photo''' [[Image:tcleft.jpg]] On the left you can see the Colour and brightness controls. '''Full Frontal''' [[Image:tcfront.jpg]] Similiar in looks to a normal Dreamcast but with an headphone port. '''Right Side photo''' [[Image:tcright.jpg]] Volume Control, Speaker (one on both sides) but an empty modem slot. '''Photo of the Bottom''' [[Image:tcbottom.jpg]] Nothing of interest there. '''Treamcast with Lid Open''' [[Image:tcopen.jpg]] Totally flat design compared to the normal Dreamcast. '''Lid Open Picture''' [[Image:tclidopen.jpg]] There you go, that's enough pictures, let's get down to buisness, onto the review. ==The Review Itself== '''The accessories bit ''' When opening the package I was impressed with the bag and the quality of it, everything was very well packaged inside. First thing I had to check was the power supply adapter and thankfully it works in the UK with the addition of a Shaver adapter (around 50p). I got the system set up very quickly and then tried the power button, the power adapter itself had a fan built into it which wasn't too noisy although you could hear it. '''The Joypad''' The Treamcast joypad is a throwback to the old Sega Megadrive/Genesis style joypad and while it was ok to use I did find the directional control a bit clicky, so for me the original joypads are much more preferable and to that there's no place where to put your [[VMU]]. '''The VCD/MP3 Player''' Well, I read the packaging and it said it also supported S-VCDs too so I was quite excited to try this, but it didn't work, the player kept on saying the controller (the IR receiver) wasn't there, so thats one bad tick from me and I will be emailing the supplier for a new Set ASAP, the remote control was ok and had the words Dream Movie on it and was good enough for the purpose, but until I can get a hold of a replacement unit, I cant say if it does play VCD 2.0/MP3/ SVCD disks. I would presume it plays VCD/MP3, the SVCD is doubtful, but let's wait and see. '''The Treamcast''' The Treamcast sounds just like the Original Dreamcast when using either CDs or GD Roms, it played everything I threw at it and that includes Commercial Games, Homebrew, Emulators, MP3 Players. The reading time was no less or more than on an original Dreamcast. The speakers played perfect throughout no crackling whatsoever, I was also surprised to see an AV port on the back of the Treamcast, so if you want, you can connect the Treamcast to your fancy big screen, but that is just an option. '''The Screen''' The main reason to purchase the Treamcast was the reason to use it in a car or anywhere that has a power supply. (For example: When you are on holiday) The TFT screen has a great picture and even on fast games it played very well, the one area i felt that it struggled on was games that were very Dark. It did play them but certainly not as good as i would have liked. '''Treamcast Good or Bad''' I'll do a Pro/Con thing then give my final viewpoint. '''Pros ''' *Portable Dreamcast (that itself is the great thing) *Playability in Car. *Price *TFT Screen (great for bright/normal light games) *Accesories/Bag/Adapters *Good Sturdy Design '''Cons''' *Clicky Joypads (might be a personal preference) and nowhere to install the VMU. *VCD/MP3/SVCD Player (didnt work) *TFT Screen (very dark games it struggles on) *Customs charges(bleh) ==Conclusion== '''Would I recommend one?''' The answer is a massive yes, apart from the commercial games there are loads of great emulators that you can play on this machine, as well as VCD players, MP3 Players and a multitude of Homebrew game ports, applications and self written games & demos. The problems are far outweighed by the good things and I'm looking forward to giving my Treamcast a lot of quality time. One thing I'll say is, that it is important who you buy from, I got mine from [http://tinyurl.com/yropq Success HK] and they have a good reputation but others do not, so be careful. '''Important Update''' A company in the UK called [http://www.gbax.com GBAX] also sell the Treamcast for a great price of £129 which is fantastic and they have a great name too, for those of you who are after a Treamcast. Thanks for reading -wraggster b2f792f8ab1632256f64987ad22e907cbbf1aff7 Duranik 0 1331 2597 2023-03-03T01:19:46Z Unknown user 0 Created page with "Duranik is an indie game development group best known in the Dreamcast scene for releasing [[Sturmwind]]. ==A brief history of Duranik== German Indie studio Duranik is comp..." wikitext text/x-wiki Duranik is an indie game development group best known in the Dreamcast scene for releasing [[Sturmwind]]. ==A brief history of Duranik== German Indie studio Duranik is composed of brothers Roland & Johannes Graf. The studio derives its name by combining Dürrsoft + Meranik. Elder brother Roland is the lead coder while Johannes is responsible for the graphical work and level design. While Duranik might seem like a new name, especially for the Dreamcast scene, the brothers have been part of the video game industry for decades. Their debut Dreamcast title ''Sturmwind'' is actually a spiritual successor to 1997's Atari Jaguar Freeware game, called ''Native''. One of the reasons why the dev team has gravitated towards the Dreamcast is because it was possible to publish games on it without buying expensive development systems. The bulk of the game is made with a standard PC and a highly customized version of Cryptic Allusion's ''KallistiOS'', the free and open source Dreamcast SDK now maintained by Lawrence Sebald, as well as other free tools. When not making games, Roland works as a Network Administrator and resides roughly between Stuttgart and Munich. His younger brother works as a Graphic Artist for a video game company in Vienna. The pair's top 5 Dreamcast games are ''Under Defeat'', ''Soul Calibur'', ''Crazy Taxi'', ''Ikaruga'' and ''Rez''. ==Interview Part 1: The Early Years== '''Before we start the interview can you please tell me a little bit about the Etymology of the name Duranik? What were Dürrsoft & Meranik?''' '''Does it mean anything?''' ''I can´t exactly remember why we came up with the name "Duranik". I think it is a pure fantasy name without any deeper meaning. Maybe this Dürrsoft and Meranik came from my brother. Its really a long time since we use this name. I think probably 20 years or more.'' '''Duranik has a rich history that spans 2 decades. So let's turn the clock back before we talk about Sturmwind. Can you recall the moment when the Graf brothers decide to be game designers and not just game players?''' ''We got an Atari ST around 1986 for Christmas. Our friends had the Amstrad CPC so we played a little around with these before we got our own computer. Back in those times it was always special to see something new for your machine. '' ''So we were typing in listings from the computer magazines, sometimes taking hours and days for a little program or game. To get this running after many hours was something very special. Downloading megabytes of data these days - you can´t even imagine how great it was getting something new for your machine every couple of weeks or even months.'' ''The ST was a great computer to start programming on your own. Easy to pick up and the hardware was simple and clean to begin with. At the beginning we did simple games in GFA Basic and later in STOS, non of these stuff was ever released though ;).'' '''1986 is almost 30 years ago, you must have been like 10 years old when you bought your first home computer and you had been playing around with a friends computer before you had yours. Wow, you guys were born to be programmers but was it simply the love of mathematics and calculations that inspired you to tinker with code or was it some video game?''' ''It was just fascinating, something you had never seen before. One of the first things I saw in terms of computer games was summer games running on a C64 somewhere in school. The animation, the graphics it all looked awesome. And the best of all: it was a lot of fun to control the player sprites on screen. '' '''Being a Sega Aficionado I have to ask what was your first Sega experience?''' ''The first time I heard or saw something from Sega was the Sega Master System. It was sold in Germany also around this time. The computer and video game magazines also wrote previews and game reviews for it. I have to say I was not terribly impressed with it. The computers at that time seemed to be much more interesting and it was very expensive and if you bought a couple of games with it even more.'' ''A couple of years later the Mega Drive was much more popular and we bought it very early.'' '''Any good memories with the MegaDrive? What did you think of all the accessories and upgrades? ''' ''Off course. The Mega Drive is a great machine back in the 90s and still today. We bought it with Castle of Illusion and Revenge of Shinobi. Lots of fun. '' Editor note: Fun fact. Before Dreamcast Duranik considered MegaDrive as a possible platform for Sturmwind. ''The Mega CD looked very interesting but it was very expensive and it had a bad reputation because of all these grainy FMV games. With the CD add on they did a bad job with the marketing in my opinion because it had some great hardware with a very good blitter. Most of the magazines did not mention these additional pieces at all. The MEGA CD was a very complex additional console on its own. The still only 64 colors out of 512 out of the box certainly had a big impact on the machine. '' ''For the 32x, well it was just to late and to expensive. A simpler addon cart with something like the Virtua Racing DSP 2 years earlier would probably been enough to get some more eye-candy games with lots of scaling and rotation effects. '' '''That is a very interesting point. But it is all in the past now and Sega fans do wish a lot of things would've been done differently between 94 - 98. I supposed they couldn't handle being thrust into the top spot. ''' '''Started acting like cocaine addicts. ''' '''But let's circle back to Duranik. What was your experience with 5th Generation console?''' '''The big 3 were not for you. Which is probably why you upgraded to Atari Jaguar?''' ''Well the Jaguar was available before those other machines, it was released end of 1993, the same year as the 3DO but 12 months before PSX/Saturn. As we had other Atari machines like the ST and Falcon it was just natural to be interested in the Jaguar. Later we modded the machine to transfer and execute code. '' ''Personally I didn't like this generation that much. At one point we had a PSX but it wasn't used all that much, we played a little with it but no comparison to the Mega Drive or SNES days. Never had a Saturn back in the 90´s but we bought a couple of them some time ago. For me the N64 was one of the most disappointing machines of all time. It was hyped beyond anything seen before and most of the games looked really bad, muddy textures, the polygon count and frame rate were below the old PSX and all covered in fog. '' ''The gaming magazines printing all this glossy SGI rendered pictures and claiming the game looks exactly like this was very funny ;)'' '''A single level demo of a shooter similar to Sturmwind was made for it. ''' '''It was released as freeware though, how come Duranik did not continue development on Jaguar? ''' '''Jaguar is free to develop for unlike Dreamcast which legally requires a license. ''' ''Native for the Jaguar was developed in 96/97, at this time it was not easily possible to release games for the machine. Like most consoles the Jaguar has a security encryption to ensure only software developed with a license could be released. This encryption key was not available and we didn't want to risk to develop a game for a long time without the possibility to release it. '' ''Years later these keys were released to the public, so today it is easy to create new Jaguar cartridges and Cd's. '' '''I See, I always thought the key was released fairly yearly.''' '''So after the native demo you guys disappeared for a very long time. Resurfacing in 2004 with Alpine Games; A game inspired by Winter Sports. Was this your first commercial release?''' ''Alpine Games was also developed over a couple of years. This is only a hobby for us like for others playing with toy trains or model planes. We don't have the pressure to release something every year. '' ''Alpine Games was the first game that was a commercial release, as it is released on a cartridge, there is no other way around it. If you have developed something over such a long time you just need to release it as a physical release these days because a huge part of the fans are collectors and you can not collect a download. '' True. I am fascinated with the fact that it was released on Lynx cartridges. '''I can understand indie developers releasing games on compact disc's. The whole reason the indie DC scene still exists is because of Dreamcast's ability to play CD-R's. If the DC was only compatible with Giga Disc's, it probably wouldn't have existed. Even then developers have a hard time releasing games. ''' '''Can you talk about how you went about releasing multiple games for Lynx?''' ''You are right, if it would have been GD-Rom only it would have probably been impossible or at least very difficult for post Sega releases, look at the Saturn, is there any unofficial CD release for this machine? And it doesn't even have an exotic disc format. '' '''On the Lynx we only released Alpine Games, the other cartridge is called "Alpine Games Bonus Cartridge", it was created for the hi-score contest and later also sold as there was constant requests for it. It consists of a couple of demos and not included events. There were only 512kb memory available so we had to cut some stuff out of the game to make it fit. ''' '''So how did you go about producing cartridges? Can you discuss the technology employed in order to release Alpine Games?''' ''The cartridges are produced by a German Lynx fellow, he did all the PCB design and produced some custom flash carts for us to finish the game. As we are not hardware guys it would have not been possible to do this on our own. The fanbase consists of a couple of hundred people, so its possible to do this stuff "by hand". '' '''The Lynx itself is a simple 8 bit machine with a beefed up blitter and sprite logic to allow some fancy zooming effects, the hardware itself is easy and very programmer friendly, in fact I would recommend it to everyone who wants to get his feet wet with some old school console programming. ''' '''So these cartridges were made from scratch by some German fellow? ''''''How about giving a shout out to the guy who made the cartridges? ''' ''Lars Baumstark is doing the cartridges, he created the first open Lynx Devkit with Bastian Schick, without their work the new games would be very hard to create. They did this to create a kit as an aid for driving schools, the Lynx was used as some sort of teaching device, but that was many years ago. '' '''I am a Millennial so through out my life I have seen Sega and Nintendo duke it out and now I am seeing Sony and Microsoft go toe to toe. I always viewed Atari as a long forgotten relic and it is absolutely amazing to see that it holds such a strong place in the hearts of Gen Y. ''' '''Do the Graf brothers have any plans to continue working on Atari hardware? Have you check out Skunkboard V3/Ghostboard by Harmless Lion/Goat Store Publishing? ''' ''We have some dev devices for various machines, also some Skunkboards but as we just finished Sturmwind it is not likely that we start something new right now, we are currently just looking around for interesting ideas and machines. '' ==Interview Part 2== So when did development formally resume development for Native? Development never did resume. It was stopped after the demo was released. Sturmwind is a completely different game, well the same people developed the game and it shares the same genre. There was no code or art assets reused, everything was started from scratch. '''So I guess the more appropriate response question would be when did work on Sturmwind formally start?''' '''Where any other platforms considered for the game in pre-production?''' We started working on Sturmwind in the end of 2006 beginning of 2007. The first couple of months were just for creating some test graphics. Real programming started in 2007. At the beginning we were looking at the Mega Drive as a possible platform. Production of cartridges seemed to difficult and Mega CD to exotic so we went with the Dreamcast instead. '''Now we all know that Max Scharl publicly revealed the game on German National Television show Neues in December 2010. When did you start approaching publishers? Did you consider any other publishers such as Hucast, Goat Store Publishing or self publishing?''' We talked to Redspotgames about two or three years before release. They heard somehow that we were developing a Dreamcast game and told us they would be interested in publishing the game. We did not talk to any other publisher as far as I remember. The only other option we considered was publishing it ourselves but as it seemed to be to much work to send and handle all packages and payment we went with the publisher option. '''3 years before the release? Sturmwind was released in April 2013. So basically Redspotgames contact you approximately 6 months before the Neues reveal?''' No it was much earlier, more like two years before the "Neues" Show. But as we knew it would still take a lot of time to finish the game there was no need to sign a contact with any publisher. '''March 2011 was a very significant month in the history of Dreamcast. Sturmwind was showcased on a Destructoid Live Show by Fabian Dohla, a representative of Sega of America. This was the first time in almost a decade Sega promoted a new Dreamcast, and an unlicensed game! This was a phenomenal mile stone for indie games in general. Can you talk about how you or Redspotgames managed to get Sega to promote the game?''' Redspot asked us to create a one level demo version a couple of weeks earlier. I don´t know how they were contacted or who exactly asked them. This was a demo of Level 1.2 if i remember correctly. '''I See. Well it was great that Sega finally acknowledged the existence of Indie Developers on Dreamcast.''' '''So a couple of months later around July 2012 Sturmwind was pushed from a Q2 Release to a Q4 Release of 11-11-2011. The most epic feat during the delay was the initiation of a Fan Only: Beta Testing Program. The final build of Sturmwind has over a dozen testers credited. What I found very interesting was Senlie Team's Roel and Jeroen Van Mastbergen were on the list as well!''' '''Who came up with the idea of such a liberal beta testing approach?''' Well i think its only normal to spend a lot of time in beta testing. In the end we spend almost 1.5 years testing and improving certain aspects of the game. It's also important to sometimes get new feedback from people who have not seen or played it before to check if you're on the right path. We also got a lot of helpful feedback from the previewers who got a early version. Of course you can't make it right for everyone so you have to simply make a cut at one point or you would do this in an infinite loop. '''Can you talk about the insights collected via the beta test?''' Most focus was spend on playability and difficulty, as the tester scale was between "pro" and "barely played anything the last 15 years". Of course this gave us some very mixed results. Something between "I can not make it through the first level" to "walk in the park". We had a forum where all beta testers could contribute but looking back now, I think this was not a good idea and we would handle that different for another project. '''So time for the tough questions. Positive hype was building up for Sturmwind, until rsg's disc printer went belly up and the release date was moved to TBA. '''The months that followed were extremely confusing and Redspot was receiving some harsh criticism from the community. Over 6 months later, on 30th June 2012 redspotgames finally announced that the game is delayed because of on going development.''' '''Why didn't either party announce earlier that the game was resuming development?''' Well the game was released in the end, I don't want to go into all details because I won't even remember them, there were a couple of issues but the biggest problem were the so called magnetboxes used in the special edition. It took much longer to get these boxes delivered than expected. We sent RSG the final version when it became clear the delivery problems were solved and worked on improvements till the last minute. '''After resolving all the production complications Sturmwind was formally given a released date for April 24th 2013. Though consumers and even distributors most notably Play-Asia had not received their orders. To exacerbate the situation customers who did receive Sturmwind started sharing pictures of how their Spaceship or casing had been broken in situation.''' '''Duranik and Redspotgames did try to resolve complaints publicly on their Facebook page and by July, it appeared most of the complaints had been resolved.''' '''Could you please elaborate on how Duranik worked with Redspotgames to address these complaints?''' Well, if we heard about complains or problems wee tried to point rsg to those forums to find a solution with those costumers, as all the shipping, publishing etc is done by Redspotgames, there is nothing else we can do about this, but as i said before, we heard only of very few complains about broken goods and we replaced them as far as I know. You will have to ask Redspotgames for more details. So post release how has your over all experience been interaction with the Dreamcast-Scene and RedSpotGames? Well we got a couple of emails from Dreamcast fans and try to answer all questions we find in forums or our facebook page, it seems that the Dreamcast scene is scattered all over the place with lots of different forums and blogs, there is not a central hub like Atari Age for the Atari Scene. '''Sturmwind is the first commercial Dreamcast game to be compatible with an SD-Card Reader. Can you talk about how it works with the game and are there any plans to release new downloadable content?''' There are a couple of things available if you use a SD Card Adapter with Sturmwind. You can save screenshots, replays, high scores on the SD Card. Sturmwind also supports downloadable content or DLC how you would call it on a modern console. We are currently working on "Sturmwind - The Doomsday Chronicles". This is a free 3 level bonus content. Hopefully we will be finished for the holiday season end of December. '''Wow, that is some epic news! Any other future plans for Durnaik?''' We are currently working on the Doomsday Chronicles addon. What we will do after that I don't know, we have done some work on the engine and a little prototype, but not decided if we will continue this route. Thank you very much for taking the time. We wish you the very best! 7ddc0ab27111991b55a65d43faecb4c55a45d187 Senile Team 0 1291 2598 2541 2023-03-03T01:49:45Z Unknown user 0 /* Games */ wikitext text/x-wiki [[Image:Senile Team Logo.jpg|300px|left]] == History == Senile Team was born in 2003 with the creation of [[Beats of Rage]]. Originally intended as nothing more than a fun little private project, Beats of Rage soon became a very popular game which was ported to Dreamcast by [[Neil Corlett]]. Following this success, the team began to work on the ambitious [[Age of the Beast]] project. However, this project was temporarily interrupted to complete [[Rush Rush Rally Racing]], which was released in 2009 and received very positive reviews. ===Why the name "Senile Team"? === ''This is probably our most-heard question. We only found that we needed a name for ourselves when Beats of Rage was almost finished, but we didn't have to think for a very long time about what it should be. We had already been using the name "Senile" for various things for years. It was originally conceived as the name for a mailing list. All the names that actually made sense were already taken, but after typing a few random words it turned out that "senile" was still available. As a name for our team it is far from meaningless though. The word "Senile" hints at old age, thus matching our interest in old-school gaming. And since senile dementia affects the memory (amongst other things), our motto became "proudly forgetting ten years of video games history". Meanwhile that should probably be about fifteen years.'' Quoted from Senile Team's ABOUT page. ===Members=== Roel (credited as "Opla" in BoR) The team's chieftain. Does most of the game design, programming and artwork. www.roelvanmastbergen.nl Jeroen (credited as "Leila" in BoR) Level editing, communications and quality control. Albatross 3D artist and animation sequence editor. Ben "Black Device" Boahene Senile Team's composer, who did the excellent soundtrack for Rush Rush Rally Racing and is currently working on Age of the Beast. Liënne ten Kate Liënne did some colouring work for Rush Rush Rally Racing, and will help finish Age of the Beast with her animator's skills. www.lienne.nl ===Former Members=== Neil Corlett ==Games== [[Beats of Rage]] - 2003 [[Rush Rush Rally Racing]] - 2009 [[Age of the Beast]] - Cancelled == See Also == [[Roel Van Mastbergen interview| Interview of Roel Mastbergen from Senile Team 9/9/10]] == External Links == *[http://www.senileteam.com/ SenileTeam.com - Official Website] *[http://www.redspotgames.com/ RedSpotGames - Publisher Website] cd779db20e84214e34a053cccf02239f36a031ae Senile Team 0 1291 2599 2598 2023-03-03T01:49:57Z Unknown user 0 /* Games */ wikitext text/x-wiki [[Image:Senile Team Logo.jpg|300px|left]] == History == Senile Team was born in 2003 with the creation of [[Beats of Rage]]. Originally intended as nothing more than a fun little private project, Beats of Rage soon became a very popular game which was ported to Dreamcast by [[Neil Corlett]]. Following this success, the team began to work on the ambitious [[Age of the Beast]] project. However, this project was temporarily interrupted to complete [[Rush Rush Rally Racing]], which was released in 2009 and received very positive reviews. ===Why the name "Senile Team"? === ''This is probably our most-heard question. We only found that we needed a name for ourselves when Beats of Rage was almost finished, but we didn't have to think for a very long time about what it should be. We had already been using the name "Senile" for various things for years. It was originally conceived as the name for a mailing list. All the names that actually made sense were already taken, but after typing a few random words it turned out that "senile" was still available. As a name for our team it is far from meaningless though. The word "Senile" hints at old age, thus matching our interest in old-school gaming. And since senile dementia affects the memory (amongst other things), our motto became "proudly forgetting ten years of video games history". Meanwhile that should probably be about fifteen years.'' Quoted from Senile Team's ABOUT page. ===Members=== Roel (credited as "Opla" in BoR) The team's chieftain. Does most of the game design, programming and artwork. www.roelvanmastbergen.nl Jeroen (credited as "Leila" in BoR) Level editing, communications and quality control. Albatross 3D artist and animation sequence editor. Ben "Black Device" Boahene Senile Team's composer, who did the excellent soundtrack for Rush Rush Rally Racing and is currently working on Age of the Beast. Liënne ten Kate Liënne did some colouring work for Rush Rush Rally Racing, and will help finish Age of the Beast with her animator's skills. www.lienne.nl ===Former Members=== Neil Corlett ==Games== *[[Beats of Rage]] - 2003 *[[Rush Rush Rally Racing]] - 2009 *[[Age of the Beast]] - Cancelled == See Also == [[Roel Van Mastbergen interview| Interview of Roel Mastbergen from Senile Team 9/9/10]] == External Links == *[http://www.senileteam.com/ SenileTeam.com - Official Website] *[http://www.redspotgames.com/ RedSpotGames - Publisher Website] 3edbe77026560a386e9c770a34aa4e913ed084c2 2618 2599 2023-03-03T02:01:01Z Unknown user 0 wikitext text/x-wiki [[Image:Senile Team Logo.jpg|300px|left]] == History == Senile Team was born in 2003 with the creation of [[Beats of Rage]]. Originally intended as nothing more than a fun little private project, Beats of Rage soon became a very popular game which was ported to Dreamcast by [[Neil Corlett]]. Following this success, the team began to work on the ambitious [[Age of the Beast]] project. However, this project was temporarily interrupted to complete [[Rush Rush Rally Racing]], which was released in 2009 and received very positive reviews. ===Why the name "Senile Team"? === ''This is probably our most-heard question. We only found that we needed a name for ourselves when Beats of Rage was almost finished, but we didn't have to think for a very long time about what it should be. We had already been using the name "Senile" for various things for years. It was originally conceived as the name for a mailing list. All the names that actually made sense were already taken, but after typing a few random words it turned out that "senile" was still available. As a name for our team it is far from meaningless though. The word "Senile" hints at old age, thus matching our interest in old-school gaming. And since senile dementia affects the memory (amongst other things), our motto became "proudly forgetting ten years of video games history". Meanwhile that should probably be about fifteen years.'' Quoted from Senile Team's ABOUT page. ===Members=== Roel (credited as "Opla" in BoR) The team's chieftain. Does most of the game design, programming and artwork. www.roelvanmastbergen.nl Jeroen (credited as "Leila" in BoR) Level editing, communications and quality control. Albatross 3D artist and animation sequence editor. Ben "Black Device" Boahene Senile Team's composer, who did the excellent soundtrack for Rush Rush Rally Racing and is currently working on Age of the Beast. Liënne ten Kate Liënne did some colouring work for Rush Rush Rally Racing, and will help finish Age of the Beast with her animator's skills. www.lienne.nl ===Former Members=== Neil Corlett ==Games== *[[Beats of Rage]] - 2003 *[[Rush Rush Rally Racing]] - 2009 *[[Age of the Beast]] - Cancelled == See Also == [[Roel Van Mastbergen interview| Interview of Roel Mastbergen from Senile Team 9/9/10]] == External Links == *[http://www.senileteam.com/ SenileTeam.com - Official Website] *[http://www.redspotgames.com/ RedSpotGames - Publisher Website] =2010 Interview= This interview was part of an open panel interview conducted by DC Emulation, Dreamcast-Scene and SegaBits. As part of our 09/09/10 Special. '''CONTENTS''' * A Brief Intro to Senile Team * Interview * Hilarios External Links ==About Senile Team== [[image:Senile Chicken.jpg|right]] [[Senile Team]] was started by brothers [[Roel Van Mastbergen|Roel]] and Jeroen Van Mastbergen, they quickly rose to popularity in the homebrew community with their tribute to Sega' Streets of Rage with [[Beats of Rage]] (BOR). In addition to being an excellent game itself, its [http://lavalit.com game engine] has been used to recreate classic arcade games for Dreamcast such as Golden Axe and the Final Fight trilogy. Last year Senile Team released [[Rush Rush Rally Racing]] (or short: R4) with publisher [[RedSpotGames]]. R4 is an old school top down 2D racing game. This year along with their publisher Senile Team attended GamesCom. We caught up with Roel Van Mastbergen of Senile Team and probed them for more information on their experiences at GamesCom and the progress of their upcoming game [[Age of the Beast]]. ==Interview== '''How was GamesCom for you?''' ''Expensive; mostly on account of train fares, but well worth it! ''This was the first time we got to talk to [http://redspotgames.com/ RedSpotGames] in person, and I think it helped strengthen our relationship. We also talked to interviewers, fans and another Dreamcast developer; KonTechs.'' ''We seldom get a chance to do that in person.'' '''Have you been to any other video game conventions?''' ''No, this was our first time, both as Senile Team and as individuals. I don't know when we'll be attending such a convention again, but I'm fairly certain we will.'' '''What was it like meeting KonTechs? Did they approach you as a competitor or did they try to offer you a publishing deal with HUCAST.net?''' ''They didn't do any of that, because KonTechs is not a competitor of ours and they are not HUCAST.net.'' ''Also, to my knowledge, Hucast.net is not really a publisher except of their own product (DUX). KonTechs is focused on technological solutions, so we talked about things like programming and possible collaboration, as well as more general subjects. Sorry, I can't give out any details, except for one thing: during the conversation it occurred to us that almost every Dreamcast developer consists of - or was founded by - brothers! Senile Team, KonTechs, Yuan Works... and the list goes on!'' (Note: KonTechs Collaborated with HUCAST.net to release DUX) '''Senile Team has had relations with both GOAT Store (At Midwest Gaming Classic 06 Age of the Beast: Special Edition was announced, an event sponsored by GOAT Store) & RedSpotGames. Can you talk us through the process of finalizing a publisher for R4?''' ''We wanted to make an informed decision, so we included both GOAT and RSG in our list of options and talked to both. RSG was the better choice for us. Arguments in favour of RSG included their geographical location, advertising strategies, graphic design, currency (no conversion between dollars and euros needed), previously published titles and the pleasant co-operation we'd experienced in the past.'' '''We were speculating that Senile Team and RSG's big reveal would have to do something with Nintendo, but our money was on DS or 3DS. Why did you choose a digital release over a physical one?''' ''Well, you should be glad you didn't bet any real money, because we're not particularly interested in Nintendo DS and 3DS at all. Personally I have worked with the Nintendo DS in the past, but found it an awkward machine to design and develop for. And we had already been working on the Wii port for several months before the 3DS was even announced. Still, it could be an interesting experiment to make a 2D game on a 3D screen, so in that respect the 3DS does have some appeal. But we really want to continue with Age of the Beast as soon as we're done with RRRR, and we can't use any more distractions.'' ''Our side questing days are over!'' ''Digital releases are attractive to small teams such as ourselves, because they generally don't require as big a budget as physical ones. With a digital release, we (or our publisher) don't have to invest in the production, storage and distribution of CD's or DVD's. Additionally, dev kits and licensing for digital releases are often cheaper and easier as well.'' [[image:Senile Team Art 3.jpg]] '''Why did you choose WiiWare for R4?''' ''As for the Wii, we had lots of reasons to consider it the best candidate for a port of R4. It supports four players and its resolution is similar to the Dreamcast's. The Wii development kit is relatively affordable. We can keep all our C code (contrary to some systems where C++ or C# must be used). And perhaps the most important one of all, I already have experience with WiiWare development. ''Of course there are down sides as well, most notably the Wii's default controller and its limited storage capacity. Fortunately we were able to map the controls to the Wii Remote's button layout fairly well, and for the best experience we added support for the Classic Controller and GameCube Controller. As for the data size, the WiiWare port has to be about one fifth the size of the Dreamcast version! Shrinking the data without losing features may well be the most time-consuming task in this entire project.'' '''What can you tell us about the PSP port of R4?''' ''Nothing at this time, sorry.'' '''Have you considered adding another R in R4 for the ports (Rush Rush Rally Racing Remix :D)?''' ''Yes, we have. But then the number of R's wouldn't match the number of players anymore.'' '''The regular edition of R4 on Dreamcast has been sold out for quite a while now. What are the chances for a later reprint with some of the PSP/WiiWare improvements?'''' ''I honestly don't know yet.'' [[Image:AOTB Art.gif|left]] '''So what is the progress of Age of the Beast anyway?''' ''Well, obviously our attention has been directed at R4 for some time, so Age of the Beast hasn't progressed much. However, the things we've learned from creating RRRR, the improvements we've made to our 2D engine and the fact that we can now look at AotB with a fresh perspective again, are all very good developments. These factors will all help to further improve the quality of AotB and to make the development go more smoothly.'' ''Bear in mind though that we are still a small team working on a very big project, so the release date remains scheduled for "when it's done".'' '''Is it true that Age of the Beast will no longer have a freeware version?''' ''True. we originally planned AOTB as a successor to BOR. As such, it was to be a combination of an original game and an update to the BOR engine. But things changed since then, in several ways: *''For those who want an updated engine to create mods with, OpenBOR is a perfectly sound option already. So it makes more sense for us to focus on the "original game" aspect.'' *''The game design for AOTB has evolved quite a lot. To implement all the ideas we have (or at least the best ones), an updated BOR engine simply will not suffice. We need to program the engine to support very specific features (e.g. complex behaviour for boss characters), whereas a moddable engine would benefit more from generalistic features. It would be too time-consuming to try to support both; we would only end up having neither.'' *'' So far, all our projects have cost us a lot of time and money. And sadly we don't have a money tree (it died some time ago after we forgot to water it). If we don't make sure our projects become economically viable, pretty soon we won't be able to make any more games at all. And that would be a shame, because we're not about to run out of ideas for at least another century.'' '''Well obviously you guys are getting busy with AOTB, but what's next?''' ''Well, over the years we've built up quite a collection of game concepts, some of which are very unique and original. So the next thing we'll be working on is a cloning machine, because creating an army of clones is obviously the only realistic way to develop so many concepts.'' We would like to thank Roel Van Mastbergen of Senile Team for taking the time for the interview. === External Links === * [http://www.senileteam.com/forum_thread(107583).html?post=107718#p107718 Senile Team @ GamesCom The Novel] * [http://dreamcast-talk.com/forum/viewtopic.php?f=21&p=24018 RedSpotGames/Senile Team's fan/Stalker @ GamesCom] [[Image:Roel Picture2.jpg]] We would like to thank Roel Van Mastbergen of Senile Team for taking the time for the interview. =2013 Intervew= [[Image:Senile Team.jpg|250px|left]] Senile Team has sort of been flying below the radar for a while, so we decided to catch up with our good friend; Senile Team’s head honcho Roel Van Mastbergen. It has been 3 years since our last interview with him so we start the interview with a walk down memory lane touching up on their past classics like Beats of Rage and Rush Rush Rally Racing. For the second half of the interview we delve into Senile Team's new adventures such as the recently released ''Polkyo’s Super Jelly Bean Quest in the Sketch Book of Illusion'' along with their other projects including an update on the fabled Age of the Beast. ''This very special interview was conducted around the time of Dreamcast's 14th Anniversary by [[Age Media]] and was shared on Dreamcast-Scene and Sega Bits in addition to DC Emulation. '' == A Walk Down Memory Lane Interview Part 1 == [[Image:Senile_Roel.jpg]][[Image:Senile_old_logo.jpg|350px||right|The Past]] [[Image:Mastbergen_Brothers.jpg|350px|right|The Mastbergen Family]] [[Image:Rolling_Thunder.jpg|350px|right|Albatross & Leila aka Sanders & Jeroen]] [[Image:BOR_Title.jpg|350px|right|A Streets of Rage tribute featuring SNK King of Fighter Characters]] [[Image:BOR_Mods.jpg|350px|right|Original (Top Left), Final Fight Mod (Top Right), X-Men Mod(Bottom Left), (Road Rash Mod (Bottom Right)]] [[Image:R4_Screens.jpg|right|350px]] [[Image:R4DX_AC.jpg|right|350px]] [[image:Lassi.jpg|right|350px]] [[Image:R4_Wii_Uk.jpg|350px|right|Number One]] === Senile Origins === '''For the uninitiated, can you please tell us how Senile Team came to be? How many members make up the studio and what are their roles? ''' Our team started as three brothers with a burning desire for another sequel to Streets of Rage. We started working on "Beats of Rage" in the beginning of 2003. Around the time we completed our project, we found that we needed a name for ourselves as a team. We chose "Senile Team". The name "senile" was originally the ID of a mailing list we'd been using, and until then didn't have any special meaning. But since our game was so old school / retro, and senility is commonly associated with elderly people who are mentally stuck in the past, it was a perfect match. Senile Team presently has five members: the three original brothers, my girlfriend Liënne and our composer Ben. Ben is from Germany, the rest of us are from the Netherlands. Liënne is a 2d artist and animator. The youngest brother wishes to be referred to as Albatross, and his primay tasks are the creation of 2D and 3D graphics and video editing. Jeroen, the middle brother, helps out in every way that doesn't involve the creation of graphics, programming or music. I myself am most often found programming, or if I get the chance, creating 2D graphics. '''Hahaha Senile Team is quite the family. Is it just me or does Albatross maintain quite a low profile? I have been following Senile Team since day one and I did not know there was a third brother involved. ''' '''I bet he’s a Shinobi fan!''' It’s not just you. His existence isn’t a complete secret, though. He is listed as a team member on our website. And actually he’s more of a Rolling Thunder fan. Hence the name “Albatross”. ;) '''Interesting. So if he was Albatross. The question is who was Leila?''' Haha that would be Jeroen. '''So Ben is an interesting member as he is a part of the Senile Team family and shares the love of Streets of Rage but isn’t a part of the Mastbergen family. How did he join the Team?''' As a fan of both SOR and BOR, Ben was one of the first to become a member of the BOR community. When we announced that we needed someone to compose the soundtrack for Age of the Beast, Ben immediately stepped up and has been a loyal team member ever since. Of course the irony is that Age of the Beast is still not completed, but he has also done an excellent job on the Rush Rush Rally Racing soundtrack. Ben wasn't the first "external" addition to our team, though. The first was Neill Corlett, who ported Beats of Rage to Dreamcast and PS2, and later helped with the code for Age of the Beast and Rush Rush Rally Racing. But unfortunately he didn't have time to spend on those projects any more, and left the team. === Beats of Rage Discussion === '''When Beats of Rage was released it was a phenomenon, I remember we proudly hosted it at DCS and 72 hours later our site crashed from the spike in traffic. Just when you think things couldn't get any more exciting you released the source code and the scene exploded. I don't think the homebrew scene was ever so active. Not only were people making spin offs for Streets of Rage, they even recreated other side scrolling classics like Double Dragon, Golden Axe, and even SOR's biggest rival Final FIght! Now that is really funny because Streets of Rage was in many ways a clone of Final Fight and now fans were using Beats of Rage engine to remake the Final Fight Trilogy. Sort of brings things full circle. '''If the resurgence of classic side scrollers wasn't overwhelming enough, fans started making beat'em ups of games that weren't even Side Scrollers such as Mortal Kombat Legacy, Kill Ryu (A Kill Bill inspired Street Fighter game). Somebody even went as far ahead to push the limits of the engine and make a Road Rash game.  '''Can you talk about the legacy of Beats of Rage?''' Well, the dozens of modded games are of course most obvious of Beats of Rage's effects. The quality varies, of course, but there's no doubt that some people have been very creative. The Road Rash mod was indeed a surprise, even if it doesn't rank amongst the best ones. Other users of the OpenBOR engine have explored other genres too, with at least one shmup, a run & gun game and various mods that blend beat 'em ups with RPG's. Some people have learned how to program, or how to draw and animate sprites just for the sake of making mods. A few even based their career choices on their experiences with Beats of Rage and openBOR. It's hard to say exactly how much influence Beats of Rage has had outside the scene, though. Clearly the vast collection of openBOR mods is a treasure trove of inspiration and information to anyone who intends to develop a beat 'em up these days, so it seems likely that other developers have already used it as such. But I guess it's impossible to know all the details. '''Allow me to highlight a variable that you might be unaware of. It may sound a little over the top but if you put it into perspective it will make all the sense in the world.  '''Dreamcast's ability to boot burned disks without hardware modification allowed the indie scene to prosper, however it was also the most pervasive reason for the systems decline, as It enabled piracy all to easily. When Sega discontinued the Dreamcast naturally software support started to decline to fill in the void BOR mods were released commercially by pirates in underdeveloped countries. ''' '''Given that PS2 required hardware modification to enable piracy and it took several years to develop a perfect mod chip, pirates really did not want the Dreamcast to vanish off store shelves, once PS2 piracy was perfected a handful of mods were released commercially on it as well.''' We are aware of the fact that Beats of Rage mods were sold by shady, parrtot shouldered types, but I'm more inclined to call that collateral damage than a legacy. Unless you mean that Beats of Rage contributed to extending the Dreamcast's life span, because that would definitely be a good thing. ;) '''The OpenBOR community continue to evolve the engine, but if you could go back and work on the engine again what would you like to do with it? ''' I could interpret that question in various ways, so I'll give you various answers. If I could go back to 2003 and work on Beats of Rage again, I would only change a few details. First of all, I would add a warning to the engine itself that it is not to be sold. Such a warning was already present in various other locations, but clearly that was not enough. I would also add the option to jump over an enemy when you've grabbed them. That was a great feature in Streets of Rage that Beats of Rage was sorely missing. Finally -- and I know that this isn't a feature of the engine but of the game -- I would improve the graphics for the final level (where you fight Mr. Y). I always meant to do that, but near the end of the project I got a bit tired/lazy. About the OpenBOR engine, of course there are some things we would have done differently than the OpenBOR team. Backwards compatibility is one thing (if you play Beats of Rage with the OpenBOR engine you'll find that it is a bit broken), and we would have opted to implement more built-in features rather than a scripting engine. But of course different people do things differently, and the OpenBOR team are doing a great job so nothing but praise for them. Also, in a very real sense we did continue to work on the engine, because an advanced version of it was going to be used for Age of the Beast. However, over time the concept of Age of the Beast has changed. Some gameplay elements will of course remain the same as they were in Beats of Rage, but the engine will be completely different in several key areas. === Rush Rush Rally Racing === '''I can't wait to discuss Aotb, but first let's talk Rush Rush Rally Racing's (R4) Marketing. '''I think it is safe to say that there has never been an indie game on any retro console that has been marketed quite like R4. Senile Team & RSG just kept pushing it. It was a presence at game conventions, it got celebrity endorsements, and it also had some pretty cool merchandise. ''' '''For those who are out of the loop can you talk about all the cool things that were done for R4 beyond designing the actual game? ''' My knowledge of other retro games' marketing is limited, so I can't say if that's entirely true. I'm sure there have been others in the same category that received a remarkable amount of attention and merch. You certainly have a point, though. There was a deluxe edition with a soundtrack and stickers, and later posters, caps and more stickers were produced. And besides redspotgames' and Senile Team's own efforts, others also helped out. There was Benzaie's awesome YouTube video. Fan art appeared on the Dreamcast Junkyard. And a number of games magazines, including quite notable ones like GamesTM, filled multiple pages with interviews and favorable reviews of the game. One of my personal favorite R4-related things was redspotgames' presence at the GamesCom in Cologne. They had a remarkably well-designed, well-built booth. Both the Dreamcast version and an early Wii version of R4 were on display, as well as of course other redspotgames products. We also met Kontechs there of Dux fame, and Josh Tari better known as Captain Dreamcast. It doesn't get much better than that! But the most unusual of all was probably the sponsoring of Formula BMW racer Lassi Halminen by redspotgames. Sadly though, what should have been a joyous occasion became a thorn in our side. The sponsoring was supposed to be promotion for the WiiWare release of Rush Rush Rally Racing, whose development was already completed at that time. But instead, it only seemed to distract redspotgames from actually publishing the game! That's got to be worth at least a triple facepalm! '''It is unfortunate that the game wasn’t released alongside its marketing campaign. It took almost 3 years for R4 to be released on WiiWare (Wii U was almost out by then). The WiiWare version still hasn’t seen a release outside Europe.   '''I think everything that could go wrong with the release of the Wii version did go wrong, in spite of all this the game did land on the top of UK WiiWare Charts. ''' '''Can you offer any insights as to why indie developers simply have no luck with Nintendo? ''' ''' It did take ridiculously long, yes. This might have been excusable if it had been a challenging game to develop, but it wasn't. The only major technical challenge was to shrink the data to less than 20% of its original size, and we managed that quite well. So not quite everything that could go wrong, did. We even had space left to add more features. It was all for naught, though, as for all our efforts we're not getting a cent in return. Consequently, there won't be a release in other regions. I'm sure that not all the factors that delayed the release of our game also applied to the other projects you mentioned, but I believe you are correct that Nintendo is one they all have in common. Although many of the people working there are certainly competent and helpful, it can't be denied that there was also a lot of bureaucracy involved. I can't really give any details because I'm under NDA, but I think everyone has a pretty good idea of what bureaucracy looks like. Lots of rules that don't make any sense and keep changing all the time. I wonder why they still took the effort to change them, because as anyone can plainly see Nintendo basically let the WiiWare service bleed to death. '''So Lassi Halminen could not do what Danica Patrick did for Sonic All-Stars Racing: Transformed? ''' Who? '''Haha, She’s just a Nascar driver who has been promoting SASRT. ''' I guess not. Nothing wrong with Lassi's driving, though. So that was our walk done memory lane. Join us next week as we delve deeper into the perils for developing for Nintendo and discuss what Senile Team has been up to post R4! == Beyond the Rush Interview Part 2 == [[Image:Poluko.jpg|right|350px]] [[Image:Sturmwind.jpg|right|350px|Senile Team participated in Game Testing]] [[Image:AgeOfTheBeast01_p.gif|right|350px|Continues to allude us]] '''Many developers have publicly revealed the perils of dealing with Nintendo. '''However, those developers have dropped Nintendo hardware as a development platform altogether.''' '''Since you are abiding to NDA's I will assume you plan to work with Nintendo in the future.''' Can you discuss things that you could do differently to get a game released on the projected date? ''' We have no plans to release anything on Nintendo hardware in the foreseeable future. But we take our agreements seriously especially when they involve legal documents and generally feel it's better to err on the side of caution. '''Can you discuss things that you could do differently to get a game released on the projected date? ''' Delays are a nuisance to players and to Senile Team. We are determined to avoid them in the future, and hope to accomplish that through a number of measures. First and foremost, we will not disclose any information about the projects we are working on until they are in a much more advanced state. After Beats of Rage, we said that we had started working on Age of the Beast and the effects of that mistake are still haunting us. If you've kept an eye on this project, you've likely seen many different release dates for Age of the Beast on various websites, but those must have sprung from the wishful minds of people who put the "dream" in Dreamcast, because the only official date is still simply "when it's done". '''You shouldn't feel haunted by it, you have given the scene OpenBOR and R4, I am sure the community can let that one slide. ''' Another important one is that we will try to keep the lines short, avoiding "middlemen". Like others before us, we've become very interested in the benefits of self-publishing. '''Has the Sturmwind debacle instigated this idea or the R4 port? ''' It's a result of on our own experiences, of course. '''Last year, Senile Team returned to their freeware roots with a port of Hot Pengu's browser game Polyko's Super Jelly Bean Quest for Dreamcast. Can you talk about how you went about bringing it to Dreamcast? ''' Sure. When I first saw the Polyko Flash game, I was quite impressed by its charming 16-colour graphics. I contacted Rik, a.k.a. HotPengu, and had a very pleasant conversation. As it turned out, he's a fan of both the Dreamcast and Beats of Rage, so it clicked and we quickly agreed to bring Polyko to the Dreamcast. The Flash game was implemented in a way that wasn't suitable for a direct port, so I basically had to rebuild it in a different way. Using the tools I had already created for Senile Team's projects, this was only a matter of days. The game is now available for free on the Senile Team website, both as a CD image and as an ISO file for use with an SD card reader. '''How has the reception been for Polyko in terms of downloads? Any server crashes? ''' Not bad I guess, but nowhere near a server crash. Not only is the average server much more powerful these days, but clearly the Dreamcast scene is also much less active than it was a decade ago. '''So I saw you and Jeroen credited in Sturmwind as Play Testers. How did you guys get involved and could you share some of the suggestions you gave? ''' We had already had some contact with Duranik as fellow Dreamcast developers, and when we were asked to help test Sturmwind we happily agreed. I think most of the issues we found were related to graphics and usability, but I can't recall the exact details. We were only involved in the testing for a short time, though. Not sure why that is. '''...Drum Roll...''' '''Last year in an interview with Sega Addicts you revealed that Age of the Beast had been rebooted and you were exploring new technology as well as looking into expanding the team. So any update that you could be share with us? ''' Well, the new technology I was referring to consists mainly of various tools I developed to increase our productivity. They are working quite well, as evidenced by the short time it took to create the DC version of Polyko. But I'm afraid that's all I can say about this subject at this time. '''Okay, no Problem. Any other updates? What about the other secret Dreamcast project? ''' A *secret* project you say? I can't imagine what you could possibly mean. '''Okay, then... This interview is ending on a very sad note Roel. Surely, you could give us something? ''' '''How about an update on the Rush Rush Rally Racing re-release the regular edition sold out 2 months after release. The DX edition sold out years ago, and DX Alternate Cover Edition sold out earlier this year. ''' Perhaps it will cheer you up if I tell you that we are working on more things to make you happy. Or don't you like surprises? ;) '''Well there you have it folks, that concludes our epic interview with Roel that took over a year to complete. Yup, just a few months shy of 2 Years!''' ''' '''I would really like to thank Roel San for all the constructive feedback and patience. I wish him and his family all the success in the world, I can't wait for Age of the Beast and would welcome a re-release of R4 in the meantime. ''' c67575a0361e8afd4d11b7084b8939e785b03043 Rush Rush Rally Racing 0 1332 2600 2023-03-03T01:51:15Z Unknown user 0 Created page with "[http://www.senileteam.com/ SENILE TEAM], creators of [[Beats of Rage]], revealed their new Dreamcast project earlier this year: It's a 'Micro Machines'-like 2D racer to be p..." wikitext text/x-wiki [http://www.senileteam.com/ SENILE TEAM], creators of [[Beats of Rage]], revealed their new Dreamcast project earlier this year: It's a 'Micro Machines'-like 2D racer to be published by the [http://www.redspotgames.com/ redspotgames]! == Initial Announcement == Here's what jeroen wrote on the [http://www.senileteam.com/forum_read.php?thread=284 Senile Team Forums]: ''In our interview with [http://www.destructoid.com/interview-with-senile-team-rage-and-beatings-ensue-27998.phtml destructoid] a month ago we mentioned that a surprise was coming, and here it is:'' * [http://www.senileteam.com/games.php Rush Rush Rally Racing]. == Features: == * 1-4 Players * Widescreen support * 4 player mode runs in 640x360 or 640x480, depending on one's settings. * 44 KHz, 16-bit stereo soundtrack. * Graphics are kind of a mix of true colour, high colour and indexed colour elements. Max colours on screen is 16.7 million. * Blending effects used for soft shadows, lights, etc. == Screenshots: == Check out some of the excellent looking screenshots at the [http://www.senileteam.com/r4shots.php official website]. == About R4 == Rush Rush Rally Racing initially was planned as a small game to submit to the DC Coding Grand Prix 2006. quoting [http://www.senileteam.com/forum_read.php?p=4023#p4023 jeroen] ''During the creation of the game, people came with bigger and better ideas. So we implemented them; it would only increase our chances of winning anyway'' ''And then Sony destroyed Lik-Sang and the competition was cancelled. At this point the game was starting to be pretty cool, so we decided to expand it further to make it a complete game that could be published.'' == Links == * [http://www.senileteam.com/forum.php?area=14 Official Forums] * [http://www.senileteam.com/r4info.php Official Website] f3f553118f8c7b145cfbbea6cabe7c47a1d53252 File:AOTB Art.gif 6 1333 2601 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=AOTB Art}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 390327dc8ea221d6a3695f749d118393e53839ed File:BOR Title.jpg 6 1334 2602 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=BOR Title}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 31d3211da6d3adf373db184848725303187f8e0b File:BOR Mods.jpg 6 1335 2603 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=BOR Mods}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8ef90ef94c532e8876867acad12a1e027edb0e9a File:Lassi.jpg 6 1336 2604 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Lassi}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 273b81257c6c958e5b73315b24bbac090d9afed3 File:Mastbergen Brothers.jpg 6 1337 2605 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Mastbergen Brothers}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e60a610319700c45537eb52093aa90112f49059d File:Poluko (1).jpg 6 1338 2606 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Poluko}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7c0cfec71d35e65cd158ce9cc55c36d1d362e43c File:Poluko.jpg 6 1339 2607 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Poluko}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7c0cfec71d35e65cd158ce9cc55c36d1d362e43c File:R4DX AC.jpg 6 1341 2608 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=R4DX AC}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} a7366ac728fb61d8e4b0aa91c52a6e0b956d996c File:R4 Wii Uk.jpg 6 1340 2609 2023-03-03T01:59:26Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=R4 Wii Uk}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8ad2c66fb4549b29a556683c2844a22d04115520 File:Roel Picture2.jpg 6 1342 2610 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Roel Picture2}} |date=2004-01-08 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 5ec92e255a42c68704ac14dee1e2247e020e5e4d File:Rolling Thunder.jpg 6 1343 2611 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rolling Thunder}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 190efd5b938d5e8ee35f2c79f778bb0514550fdd File:Senile Chicken.jpg 6 1344 2612 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Senile Chicken}} |date=2010-09-09 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} ffa0e264d1aca041e43fdf2df587e04ba35a318d File:Senile old logo.jpg 6 1345 2613 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Senile old logo}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 313f48e8851f1d0e503dcdecd15919a957f2e9a3 File:Senile Roel.jpg 6 1346 2614 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Senile Roel}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} dd28f50350a85526e5a95e91adf629e32137be38 File:Senile Team Art 3.jpg 6 1347 2615 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Senile Team Art 3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d9723c50085f529852d58cb226ca5ad338d402d6 File:Senile Team.jpg 6 1348 2616 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Senile Team}} |date=2009-08-18 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 9ed36a3b35a2e3db1da3e2b6f90e3aeb3548ed29 File:Sturmwind.jpg 6 1349 2617 2023-03-03T01:59:27Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Sturmwind}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7b177bb1b137c147b8a5defa7c49a8bc6d22a956 File:IsotopeInterview3.jpg 6 1350 2619 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview3}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 2c2c359a174f8d295e22599c2777e9862c210dbf File:IsotopeInterview2.jpg 6 1351 2620 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview2}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 915479a7997b256f008b151e2d2cb2b30f556c6d File:IsotopeInterview.png 6 1352 2621 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 8eb8a04a7ad4d088181dc65d22be1a8fa7734b9a File:IsotopeInterview5.jpg 6 1353 2622 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview5}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 974bcafd67927a4a01bf0f40b07cb167ec827e42 File:IsotopeInterview7.jpg 6 1354 2623 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview7}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 426b80bf2f2322d7975abd84c8f54ffcdd23d283 File:IsotopeInterview6.jpg 6 1355 2624 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview6}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d7c2c820a8c388cc3b58d254229822ca3524768d File:IsotopeInterview8.jpg 6 1356 2625 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview8}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 4c45cf495e24522bf6b94c42e73f83d4c6c877e7 File:IsotopeInterview9.jpg 6 1357 2626 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterview9}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e0f573daa158ebbe78cca2507169a5d49086018d File:IsotopeInterviewX.jpg 6 1358 2627 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeInterviewX}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} f0daa567874c251a6c22a212bbebbe78996b0515 File:IsotopeStudiosLogo.jpg 6 1359 2628 2023-03-03T02:10:14Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=IsotopeStudiosLogo}} |date=2023-03-02 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 35e3e88c79924e6021e9a21fe259ca100678df9c Isotope Studios 0 1360 2629 2023-03-03T02:10:35Z Unknown user 0 Created page with "Isotope Studios was an independent game development group known for the unreleased games Scourge and Hypertension: Harmony of Darkness using the [[Dream3DGE Engine]]. See als..." wikitext text/x-wiki Isotope Studios was an independent game development group known for the unreleased games Scourge and Hypertension: Harmony of Darkness using the [[Dream3DGE Engine]]. See also: *[https://dcemulation.org/phpBB/viewtopic.php?t=102580 Isotope Studios Launches New Site] *[https://dcemulation.org/phpBB/viewtopic.php?t=102637 Isotope Studios Releases Dream3DGE Game Engine] == Interview == [[Image:IsotopeStudiosLogo.jpg|left|300px]] [[Isotope Studios]] is an independent game developer currently working on its first two games: [[Scourge]] and [[Hypertension: Harmony of Darkness]]. Both games are 3D horror games for the [[SEGA]] [[Dreamcast]], though a release date has not yet been set. == In This Interview == [[Corbin Annis]] - Creative Director, Lead Designer [[Bruno Aste]] - Lead Artist [[Jason Johnson]] - Lead Modeler == Interview == [[Image:IsotopeInterview.png|right|500px]] [[Image:IsotopeInterview2.jpg|right|500px]] [[Image:IsotopeInterview3.jpg|right|500px]] [[Image:IsotopeInterviewX.jpg|right|500px]] [[Image:IsotopeInterview6.jpg|right|500px]] [[Image:IsotopeInterview5.jpg|right|500px]] [[Image:IsotopeInterview8.jpg|right|500px]] [[Image:IsotopeInterview7.jpg|right|500px]] [[Image:IsotopeInterview9.jpg|right|500px]] '''So you've got two games in the works right now: Scourge and Hypertension. Can you start by telling our readers a little bit about each game?''' CORBIN: Sure thing! Hypertension: Harmony of Darkness (HoD) is a first-person arcade-style game, heavily influenced by Monolith's shooter, Blood. It uses our in-house [[3DGE engine]], which itself is a heavily modified [[DOOM]] engine, and supports things like 3D models, true 3D floors, and awesome dynamic lighting. Other enhancements include a splitscreen mode for two-player deathmatch or cooperative play. Hypertension is basically a story about a man risen from the dead to avenge the death of his lover. Over the course of the game, he fights his way across the 1920s United States to take down a psychotic cult before they can resurrect dark beings known as the Deep Ones. This leads directly into Scourge's main story. Scourge is a 3D psychological thriller, using a hybrid first-person/third-person system. It is powered by the award-winning [[Quake 2]] engine, which served as the technology for such games as [[Soldier of Fortune]], SiN, Anachronox, and [[Half-Life]]. Set in 1928, you play as Kaiven, a P.I. hired to find a mad scientist's wife who had run away 20 years earlier. However, when Kaiven arrives in the small coastal town of Miskatonik, he learns that there's more than meets the eye to this haunted locale, and he soon finds himself battling otherworldly monsters and spirits. BRUNO: Scourge is a first- and third-person survival horror game partly inspired by the works of HP Lovecraft and classic horror films and video games. It takes place during the 1920s, which is a great setting for incorporating literary concepts related to the Lovecraft mythos, such as the idea of cosmic horror and early sci-fi. This goes a long way in helping us to create an immersive world to set the narrative in. '''Over the last decade or so, first-person shooters have put an increasing emphasis on telling a detailed story. It sort of started with Half-Life and has ultimately led to games like BioShock: Infinite, which some would say focus more on story than on the gameplay. How big a role does the story play in Scourge, and as a game designer, how do you balance that with gameplay?''' CORBIN: Story plays a role, yes, but we have taken some design cues from Alone in the Dark and the more recent Resident Evil 4. In AitD, the story progresses through text books (no cutscenes), which keeps the focus on gameplay, but if players don't catch all of the references, they don't really get the story. RE4 has a few cutscenes, but the story mostly unfolds quick interludes that don't hamper the gameplay experience. The cutscenes are very short and sweet. Fatal Frame II plays much like this, too, so we're trying to take cues from games that do as little as possible to interrupt the player from the game. I feel story nowadays holds your hand and forces you through long dialogue and boring sequences. They are bombastic and can be entertaining, but these long cutscenes ends up making many titles just as much a movie as a game nowadays. The interactivity isn't there like it is in, say, Half-Life 2 or Doom 3. BRUNO: The way I see it, there have been some steps forward and some steps back when it comes to storytelling in first-person shooters. However, I would be more inclined to think of Scourge as a horror game first, which just happens to have a first-person twist, since I believe the horror genre has been doing story very well over the last decade and even longer. The pacing of the story and how it interacts with the gameplay aspects has been nailed on the head over and over by many titles, both from Japanese and western developers. '''Hypertension was based on an earlier project called Blood. How did that project evolve into its current form, and how does Hypertension tie into Scourge?''' CORBIN: [[Atari]]. There were licensing issues that we faced when Atari got involved with Blood/Hypertension, and since we are independent and were not sponsored at the time, we decided to put it on the backburner. When we got sponsored a few months later, we were given a choice: redo those assets, or start fresh. Since I've been swirling a game idea around my head for years, we decided to start fresh and abandon the previous game. We initially started developing Scourge on the 3DGE engine, but I quickly learned that the game was too complex for the engine to handle, so we chose the Quake 2 engine as a replacement. However, the Quake 2 engine is nothing like the Quake 1 engine (which we had more experience with), and it took us several years of hacking it up to get it to support the kind of game we wanted to create. Scourge itself went through a dozen redesigns away from the original Hypertension concept, but there are still many similarities, and ultimately we decided to tie the story together with Hypertension: HoD. Since HoD restarted development earlier this year, the tie-in was a no-brainer, and many fans were happy. I mean, if Game Informer shared it on their website (in 2009, I think), then it was something special that I felt could evolve away from all of the original Blood assets we used. The assets were thrown out, we'd written something like 10,000 lines or more of code, so that stayed. I make modifications as necessary to adapt the game to the revised concept, but overall the game was already about 85% complete. '''Isotope was formed specifically to create Scourge. What got you involved in Dreamcast development, and how did the team come together?''' CORBIN: I've always had a soft spot for the Dreamcast, so it was an easy choice. I used to be in awe of the homebrew created for it. So a few years ago, I teamed up with [[Chui]] to bring Hypertension to the Dreamcast. After I saw it running, I knew that's where I wanted to be. After the Hypertension project bombed, well, the rest is history. Our sponsor contracted us for a new game, and slowly but surely, a full development team was formed. Old message boards formed for Quake 2 were prominent in the late 90s and early 2000's, but with the closure of Gamespy, a lot of those were lost. I rifled through message boards and found an interested person who loved the idea and concept. From there, we just hit all of the old hangouts, but nobody was really interested in working on a deprecated technology. At that point, Bruno had a great idea: asking designers who worked with Hammer, Valve's Source engine. Since the Source engine started with Quake 1's codebase, we found that levels can be converted back and forth with relatively little effort. So, he got the genius idea to start pursuing these people, and now two of our level designers map in Hammer, which Bruno ports down. He uses Radiant, which is native Quake 2, so some details are lost… but overall, it's a great system. BRUNO: It certainly wasn't easy to get talented artists working on a Dreamcast game, and it's been even harder to handle the problems that come with working with stuff like legacy formats and old tools/hardware that are often undocumented. it's been an uphill battle, but the team is always learning and building on that experience. Recruiting was hard, since it just wouldn't cut it to get a talented person to work on the project. There was a shift in the way we handled development, so now technical skills are just as important--if not more so--than raw talent or creativity. Problem-solving fills most of our schedule these days, so the modding community is where some of our hardest-working members come from. JASON: I know, for me, Dreamcast development has always been a passion. I can remember when I first saw Sonic Adventure in 1999: the sheer feeling of awe I had for the overall experience of the Dreamcast. No system before or since has made me feel quite the way the DC does. I was engulfed early on, and as 2000 came to a close, I remember thinking, "This is what I want to do with my time!" Of course, back then I had nothing but pure passion. I researched graphics programs to get a feel for how it was done, and I spent hours reading and doing tutorials just to find out how game design actually took place. Needless to say that back then, I was in WAAAAY over my head. So it goes that the passion boiled back up periodically throughout the next decade, leaving me with little else but dreams and a lot of used space on my respective hard drives. One day, the itch got the better of me, and I felt the need to find out what sort of Dreamcast development people had undertaken in the generation of PS3s and 360s, so I again started gathering tools and researching. Then, I came across images and info for Isotope's project, and was literally amazed by the information and resources these guys were involved with. To see other people with the kind of passion that I had for the off-white box ended up drawing me in closer, and I contacted the team to commend them on their work. One thing led into another, and before I had a chance to second-guess myself, I was passing off models and issuing character designs to help with this current project. I honestly haven't looked back since I began, and have this sense that I can finally be incorporated with a group of people who can or have seen and experienced the sheer magic of the Dreamcast. To me, it truly is a timeless machine, and I feel it's poised for a serious revival in the indie scene. '''The Dreamcast was released in 1998 in Japan, and 1999 for the rest of the world. That's a 15-year-old piece of hardware, and most of us carry around cell phones that would put it to shame in terms of horsepower. Have you needed to change your game designs at all after running into limitations?''' CORBIN: No, we did the smart thing: designed Scourge with the hardware in mind. There's nothing that we've had to scrap because of hardware limitations, and choosing an engine that would work well on the system ended up being a great thing. However, that's not saying it's been easy to port; the programmer in charge of the port had to rewrite the renderer and all sorts of other things. The lead programmer spliced all kinds of things into the engine… for example, some from Return to Castle Wolfenstein, which powers our heavily modified camera code. id Technology really ports well back and forth. We've been extremely lucky with the talent behind our project. BRUNO: There are still people porting engines and games for the Atari and Amiga systems from the late 80s and early 90s. Call it a labor of love, but for us it's quite a challenging goal we set out to accomplish, to use just enough polygons, textures, and effects in order to tell our story without bogging the game down. As far as design limitations go, there haven't been many that I can remember, since we're building the game from the ground up with the target platform in mind. There was some friction in the development pipeline very early on, but we got it ironed out pretty quickly. '''What sorts of development tools have you used to create these games?''' CORBIN: Oh boy, everything from Radiant to Hammer and back. The modeling programs are interesting: we design an extremely high-poly model, bake the details into a model (1K polys or less for characters), and piece them together that way. It's a really interesting way to do it, and I doubt many teams do this. That's why we're able to get so many details into the skins. It makes them appear that their polygon count is off the charts, but really, everything is designed with limitations in mind. Some old programs from the Quake 2 era (dated, not old-school, so they are a pain in the ass to work with), some from the DOOM era, and lots from this era. It really depends on what we're doing. BRUNO: We're trying to use free tools whenever we can, so our developers don't have to struggle with formats and licenses. There's a lot of Gmax, Netradiant, Quark, Blender, Sculptris, Gimp, Xnormal, Misfit3d, and even some old, obscure--but freeware--applications from back in the day for handling skins and non-proprietary formats such as md2. '''Do you have any advice for a new developer who might be interested in creating a title for Dreamcast?''' CORBIN: Yep: EXPERIENCE! Get your experience as early as you can. Designing something easy like Hypertension (I served as lead programmer, as well as occasional modeler/level designer/etc.) where you can acquire all of those skills is a must. Get your name and your game out there. If it wasn't for Diehard GameFAN and Game Informer, we might not be anywhere at all. Show people you have something under your belt, as something like 95% of projects fail in their first year. If you already have something completed that you can point to, people will love you so much more, and actually believe in what you're trying to accomplish. Take it from me! BRUNO: If you're interested in developing a title for a 15-year-old console, you either already know what you're getting into, or you're about to learn the hard way. A good place to start is to do the math on how much power the Dreamcast really has in terms of polygons rendered on screen each frame, and plan accordingly either to go for a full 60 fps or make the (likely) compromise to go for 30 fps. Calculate how big a texture you need to fill the console's RAM when loading a level with them, plan out what the poly count will be across different game assets, optimize the level design (which is most of what the engine is doing at any given time), study the Dreamcast's graphics infrastructure (for instance, one difference from modern hardware is that you have no shaders to work with), plan out which features you will cut when forced to make a compromise, and determine what is essential to telling your story and what is just padding that looks cool but maybe you can do without. Last but perhaps most important would be to work with a precedent. If someone has made something happen on the Dreamcast or an earlier console, chances are you can do it. This of course goes not only for the technical aspects, but also when it comes to the art department; we humbly stand on the shoulders of giants. While it may seem like a safe bet for an independent company to develop for older hardware and not have to deal with shaders and all those new thingamajigs, you have to remember this is still a full-time job. I recently saw a progress report from indie game developer explodingrabbit, and it's a great watch because it clearly shows that even though some team members can work on a title part-time, you need someone to work full-time on the project if you're expecting it to get anywhere. Even with the funding they had from their website and donations (something we lack), they're aiming for a 2014 release. Also unlike us, they are working on a 2D platformer for Windows or browsers, so our project has more quirks and potential hiccups than your typical indie title. The biggest investment you can make is investing time to get in there and get your hands dirty! JASON: My advice is quite frankly to "do your homework!" It's essential to educate yourself on the respective ins and outs of your specific hardware, middleware, and software. Especially in the case of the Dreamcast, where most of its true innovations and capabilities were discovered late in--or even after--its normal life cycle, it is incredibly important to know your stuff! There's a lot of documentation out there for any prospective teams looking to devote their time to a project on SEGA's beloved box, so look sharp! It also pays to find a team that suits your ambition and has a suitably technical approach to their ideas and how to bring them about. But even through knowing the limits and specs, stay with what you're passionate about. Getting started could be as simple as modding some assets in an engine, or simply getting a sprite to animate as it moves a few pixels, but you can only ever truly be limited by your drive and resoursefulness! '''When will we able to get Scourge and Hypertension, and how much will they cost?''' BRUNO: I'm going to go out on a limb and estimate mid to late 2014. But clear dates and other specifics are beyond my ability to predict at this point. '''Are you planning any future titles once Scourge is completed?''' CORBIN: I've kicked the ball around, but nothing is certain as of yet. A project called Nightmare Onida is probably what we'll do next, which is a similar type of game to Scourge, but you never know. We've covered first-person shooters, third-person shooters, so maybe a platformer, sidescroller, who knows? Time will tell. ''DCEmulation.org extends a special thank you to the members of Isotope Studios for taking the time to participate in this interview, and for supplying the included screenshots and development images.'' == External links == [http://tdgmods.wix.com/isotopestudios]Isotope Studios [https://www.facebook.com/pages/Isotope-TDGMods/]Isotope Studios (Facebook) [http://edge2.sourceforge.net]3DGE engine (SourceForge) ''Interview conducted by [[DaMadFiddler]] via email on 9/18/13 for DCEmulation.org'' c14c9ddcbd6e80f896c4c0f6398f872bf37c0052 Licensed games and software 0 144 2630 560 2023-03-03T06:23:59Z Unknown user 0 /* List of official Western games */ wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title |- |102 Dalmations - Puppies to the Rescue | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= {| class="wikitable" ! North American title ! PAL title |- | |Dreamkey Version 1.0 |- | |Dreamkey Version 1.5 |- | |Dreamkey Version 2.0 |- |PlanetWeb Browser 1.0 | |- |PlanetWeb Browser 2.0 | |- |PlanetWeb Browser 2.62 | |- |PlanetWeb Browser 3.0 |} =List of North American demos= {| class="wikitable" ! Title |- |Airforce Delta Demo Disc |- |Army Men - Sarge's Heroes Demo Disc |- |Dead or Alive 2 Demo CD |- |Demolition Racer - No Exit Demo Disc |- |Gauntlet Legends Demo CD |- |Generator, Vol. 1 |- |Generator, Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 3 |- |Official Sega Dreamcast Magazine Vol. 4 |- |Official Sega Dreamcast Magazine Vol. 5 |- |Official Sega Dreamcast Magazine Vol. 6 |- |Official Sega Dreamcast Magazine Vol. 7 |- |Official Sega Dreamcast Magazine Vol. 8 |- |Official Sega Dreamcast Magazine Vol. 9 |- |Official Sega Dreamcast Magazine Vol. 10 |- |Official Sega Dreamcast Magazine Vol. 11 |- |Power Stone Retail Demo Disk |- |Ready 2 Rumble Boxing Demo Disc |- |San Francisco RUSH 2049 Demo CD |- |Sonic Adventure 2 - The Trial |- |Super Magnetic Neo Demo CD |- |Tony Hawk's Pro Skater Demo CD |- |Ultimate Fighting Championship Demo Disc |} =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= cc025d4c4d8395376c163c813b960c221d46c46b 2631 2630 2023-03-03T06:28:12Z Unknown user 0 /* List of officially released MIL-CDs */ wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title |- |102 Dalmations - Puppies to the Rescue | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= {| class="wikitable" ! North American title ! PAL title |- | |Dreamkey Version 1.0 |- | |Dreamkey Version 1.5 |- | |Dreamkey Version 2.0 |- |PlanetWeb Browser 1.0 | |- |PlanetWeb Browser 2.0 | |- |PlanetWeb Browser 2.62 | |- |PlanetWeb Browser 3.0 |} =List of North American demos= {| class="wikitable" ! Title |- |Airforce Delta Demo Disc |- |Army Men - Sarge's Heroes Demo Disc |- |Dead or Alive 2 Demo CD |- |Demolition Racer - No Exit Demo Disc |- |Gauntlet Legends Demo CD |- |Generator, Vol. 1 |- |Generator, Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 3 |- |Official Sega Dreamcast Magazine Vol. 4 |- |Official Sega Dreamcast Magazine Vol. 5 |- |Official Sega Dreamcast Magazine Vol. 6 |- |Official Sega Dreamcast Magazine Vol. 7 |- |Official Sega Dreamcast Magazine Vol. 8 |- |Official Sega Dreamcast Magazine Vol. 9 |- |Official Sega Dreamcast Magazine Vol. 10 |- |Official Sega Dreamcast Magazine Vol. 11 |- |Power Stone Retail Demo Disk |- |Ready 2 Rumble Boxing Demo Disc |- |San Francisco RUSH 2049 Demo CD |- |Sonic Adventure 2 - The Trial |- |Super Magnetic Neo Demo CD |- |Tony Hawk's Pro Skater Demo CD |- |Ultimate Fighting Championship Demo Disc |} =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= {| class="wikitable" ! Title |- |Checkicco - Checkicco no Miru |- |D no Shokutaku 2 |- |dps - Heart Break Diary |- |Hang the DJ |- |Himitsu - Original Sound Track |- |Kita he - Pure Songs and Pictures |- |Snappers - 09 Chairs |- |Space Channel 5 |} f10a921f155fd39ef42759a8218b20dd1cabfee7 2632 2631 2023-03-03T06:37:27Z Unknown user 0 /* List of official Western software */ wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title |- |102 Dalmations - Puppies to the Rescue | |- |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |- |AeroWings 2 |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= {| class="wikitable" ! North American title ! PAL title |- | |Dreamkey Version v1.006 |- | |Dreamkey Version v1.008 |- | |Dreamkey Version 1.5 v1.000 |- | |Dreamkey Version 1.5 v1.001 |- | |Dreamkey Version 1.5 v1.003 |- | |Dreamkey Version 2.0 v1.000 |- | |Dreamkey Version 2.0 v1.001 |- | |Dreamkey Versao 2.0 v1.003 |- | |Dreamkey 3.0 v1.001 |- | |Dreamkey 3.1 v1.000 |- |PlanetWeb Browser v1.124 | |- |PlanetWeb Browser v1.125 | |- |PlanetWeb Browser v2.004 | |- |PlanetWeb Browser with SegaNet v2.100 | |- |PlanetWeb Browser 2.62 a.k.a. v2.613 | |- |PlanetWeb Browser 3.0 |} =List of North American demos= {| class="wikitable" ! Title |- |Airforce Delta Demo Disc |- |Army Men - Sarge's Heroes Demo Disc |- |Dead or Alive 2 Demo CD |- |Demolition Racer - No Exit Demo Disc |- |Gauntlet Legends Demo CD |- |Generator, Vol. 1 |- |Generator, Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 3 |- |Official Sega Dreamcast Magazine Vol. 4 |- |Official Sega Dreamcast Magazine Vol. 5 |- |Official Sega Dreamcast Magazine Vol. 6 |- |Official Sega Dreamcast Magazine Vol. 7 |- |Official Sega Dreamcast Magazine Vol. 8 |- |Official Sega Dreamcast Magazine Vol. 9 |- |Official Sega Dreamcast Magazine Vol. 10 |- |Official Sega Dreamcast Magazine Vol. 11 |- |Power Stone Retail Demo Disk |- |Ready 2 Rumble Boxing Demo Disc |- |San Francisco RUSH 2049 Demo CD |- |Sonic Adventure 2 - The Trial |- |Super Magnetic Neo Demo CD |- |Tony Hawk's Pro Skater Demo CD |- |Ultimate Fighting Championship Demo Disc |} =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= {| class="wikitable" ! Title |- |Checkicco - Checkicco no Miru |- |D no Shokutaku 2 |- |dps - Heart Break Diary |- |Hang the DJ |- |Himitsu - Original Sound Track |- |Kita he - Pure Songs and Pictures |- |Snappers - 09 Chairs |- |Space Channel 5 |} a1fdb1e9d70635e30ad6e137735a969f03c1b588 2633 2632 2023-03-03T06:41:18Z Unknown user 0 /* List of official Western games */ wikitext text/x-wiki =List of official Western games= {| class="wikitable" ! North American title ! PAL title |- |102 Dalmations - Puppies to the Rescue |102 Dalmations - Puppies to the Rescue |- |18 Wheeler - American Pro Trucker |18 Wheeler - American Pro Trucker |- |4 Wheel Thunder |4 Wheel Thunder |- |4x4 EVO |''unreleased'' |- |''unreleased'' |90 Minutes Championship Football |- |AeroWings |AeroWings |- |AeroWings 2 |AeroWings 2: Airstrike |- |Airforce Delta |- |Alien Front Online |''unreleased'' |- |Alone in the Dark - The New Nightmare |Alone in the Dark - The New Nightmare |- |''unreleased'' |Aqua GT |- |Armada |''unreleased'' |- |Army Men - Sarge's Heroes |Army Men - Sarge's Heroes |- |Atari Anniversary Edition |''unreleased'' |- |BANG! - Gunship Elite |''unreleased'' |- |Bangai-O |- |Blue Stinger |- |Bomberman Online |''unreleased'' |- |Bust-A-Move |- |Buzz Lightyear of Star Command |- |Caesars Palace 2000 - Millennium Gold Edition |- |Cannon Spike |- |Capcom vs. SNK |- |Carrier |- |Centipede |''unreleased'' |- |Championship Surfer |- |Charge 'n Blast |- |Chicken Run |- |ChuChu Rocket! |- |Coaster Works |- |Confidential Mission |- |Conflict Zone - Modern War Strategy |- |Crazy Taxi |- |Crazy Taxi 2 |- |[[Cyber Troopers - Virtual On Oratorio Tangram]] |- |D2 |''unreleased'' |- |Dave Mirra Freestyle BMX |- |Daytona USA |- |Dead or Alive 2 |- |Death Crimson OX |''unreleased'' |- |Deep Fighter |- |Demolition Racer - No Exit |''unreleased'' |- |Dino Crisis |- |Dinosaur |- |Donald Duck - Goin' Quackers |- |Draconus - Cult of the Wyrm |- |DragonRiders - Chronicles of Pern |- |Ducati World - Racing Challenge |- |Dynamite Cop! |- |Ecco the Dolphin - Defender of the Future |- |ECW Anarchy Rulz |- |ECW Hardcore Revolution |- |Elemental Gimmick Gear |''unreleased'' |- |ESPN International Track & Field |- |ESPN NBA 2night |''unreleased'' |- |''unreleased'' |European Super League |- |Evil Dead - Hail to the King |- |''unreleased'' |Evil Twin - Cyprien's Chronicles |- |Evolution - The World of Sacred Device |- |Evolution 2 - Far Off Promise |- |''unreleased'' |Exhibition of Speed |- |Expendable |- |''unreleased'' |F1 Racing Championship |- |F1 World Grand Prix |- |''unreleased'' |F1 World Grand Prix II |- |F355 Challenge - Passione Rossa |- |Fatal Fury - Mark of the Wolves |''unreleased'' |- |Fighting Force 2 |- |''unreleased'' |Fighting Vipers 2 |- |Flag to Flag |''unreleased'' |- |Floigan Bros. - Episode 1 |- |Frogger 2 - Swampy's Revenge |''unreleased'' |- |Fur Fighters |- |Gauntlet Legends |- |''unreleased'' |Giant Killers |- |GigaWing |- |GigaWing 2 |''unreleased'' |- |Grand Theft Auto 2 |- |Grandia II |- |The Grinch |- |Gunbird 2 |- |Gundam - Side Story 0079 - Rise from the Ashes |''unreleased'' |- |''unreleased'' |Headhunter |- |Heavy Metal - Geomatrix |- |Hidden & Dangerous |- |The House of the Dead 2 |- |Hoyle Casino |''unreleased'' |- |Hydro Thunder |- |Illbleed |''unreleased'' |- |Incoming |- |Industrial Spy - Operation Espionage |''unreleased'' |- |Iron Aces |- |Jeremy McGrath Supercross 2000 |- |Jet Grind Radio |- |''unreleased'' |Jimmy White's 2 - Cueball |- |Jojo's Bizarre Adventure |- |Kao the Kangaroo |- |The King of Fighters - Dream Match 1999 |''unreleased'' |- |The King of Fighters Evolution |''unreleased'' |- |The Last Blade 2 |''unreleased'' |- |Legacy of Kain - Soul Reaver |- |Looney Tunes Space Race |- |Magforce Racing |- |Maken X |- |Mars Matrix |''unreleased'' |- |Marvel vs. Capcom - Clash of Super Heroes |- |Marvel vs. Capcom 2 |- |Matt Hoffman's Pro BMX |''unreleased'' |- |Max Steel - Covert Missions |''unreleased'' |- |Maximum Pool |''unreleased'' |- |MDK 2 |- |Metropolis Street Racer |- |Midway's Greatest Arcade Hits Volume 1 |- |Midway's Greatest Arcade Hits Volume 2 |''unreleased'' |- |''unreleased'' |MoHo |- |Monaco Grand Prix |- |Mortal Kombat Gold |- |Mr. Driller |- |Ms. Pac-Man - Maze Madness |''unreleased'' |- |MTV Sports - Skateboarding Featuring Andy Macdonald |- |Namco Museum |''unreleased'' |- |NBA 2K |- |NBA 2K1 |''unreleased'' |- |NBA 2K2 |- |NBA Hoopz |- |NBA Showtime - NBA on NBC |- |NCAA College Football 2K2 - Road to the Rose Bowl |''unreleased'' |- |The Next Tetris - On-line Edition |- |NFL 2K |''unreleased'' |- |NFL 2K1 |''unreleased'' |- |NFL 2K2 |''unreleased'' |- |NFL Blitz 2000 |- |NFL Blitz 2001 |''unreleased'' |- |NFL Quarterback Club 2000 |- |NFL Quarterback Club 2001 |''unreleased'' |- |NHL 2K |- |NHL 2K2 |''unreleased'' |- |Nightmare Creatures II |- |Omikron - The Nomad Soul |- |Ooga Booga |''unreleased'' |- |Outtrigger |- |PenPen TriIcelon |- |Phantasy Star Online |- |Phantasy Star Online Ver. 2 |- |''unreleased'' |Planet Ring |- |Plasma Sword - Nightmare of Bilstein |- |POD - Speedzone |- |Power Stone |- |Power Stone 2 |- |Prince of Persia |''unreleased'' |- |''unreleased'' |Pro Pinball Trilogy |- |Project Justice |- |Psychic Force 2012 |- |Q-bert |''unreleased'' |- |Quake III Arena |- |Railroad Tycoon II - Gold Edition |- |Rayman 2 - The Great Escape |- |Razor Freestyle Scooter |- |Re-Volt |- |Ready 2 Rumble Boxing |- |Ready 2 Rumble Boxing Round 2 |- |Red Dog - Superior Firepower |- |Reel Fishing - Wild |''unreleased'' |- |Resident Evil - Code Veronica |- |Resident Evil 2 |- |Resident Evil 3 - Nemesis |- |''unreleased'' |Rez |- |The Ring - Terror's Realm |''unreleased'' |- |Rippin' Riders Snowboarding |- |Roadsters |- |Samba de Amigo |- |San Francisco Rush 2049 |- |Seaman |''unreleased'' |- |Sega Bass Fishing |- |Sega Bass Fishing 2 |''unreleased'' |- |Sega GT |- |Sega Marine Fishing |''unreleased'' |- |Sega Rally 2 |- |Sega Smash Pack Volume 1 |''unreleased'' |- |''unreleased'' |Sega Worldwide Soccer 2000 |- |''unreleased'' |Sega Worldwide Soccer 2000 Euro Edition |- |Seventh Cross Evolution |''unreleased'' |- |Shadow Man |- |Shenmue |- |''unreleased'' |Shenmue II |- |Silent Scope |- |Silver |- |Skies of Arcadia |- |Slave Zero |- |SnoCross - Championship Racing |- |Soldier of Fortune |- |Sonic Adventure |- |Sonic Adventure 2 |- |Sonic Shuffle |- |Soul Calibur |- |Soul Fighter |- |South Park - Chef's Luv Shack |- |South Park Rally |- |Space Channel 5 |- |Spawn - In the Demon's Hand |- |Spec Ops II - Omega Squad |- |Speed Devils |- |Speed Devils - Online Racing |- |Spider-Man |- |Spirit of Speed 1937 |- |Sports Jam |''unreleased'' |- |Star Wars - Demolition |- |Star Wars - Episode I - Jedi Power Battles |- |Star Wars - Episode I - Racer |- |StarLancer |- |Street Fighter Alpha III - 3rd Strike |- |Street Fighter Alpha III - Double Impact |- |Striker Pro 2000 |- |''unreleased'' |Stunt GP |- |Stupid Invaders |- |Super Magnetic Neo |- |Super Roundabout - San Francisco Edition |- |Surf Rocket Racers |- |Suzuki ALSTARE Extreme Racing |- |Sword of the Berserk - Guts' Rage |- |Sydney 2000 |- |''unreleased'' |Taxi 2 |- |Tech Romancer |- |Tee Off |- |Tennis 2K2 |- |Test Drive 6 |''unreleased'' |- |Test Drive Le Mans |- |Test Drive V-Rally |- |TimeStalkers |- |TNN Motorsports Hardcore Heat |- |Tokyo Xtreme Racer |- |Tokyo Xtreme Racer 2 |- |Tom Clancy's Rainbow Six |- |Tom Clancy's Rainbow Six - Rogue Spear |- |Tomb Raider - The Last Revelation |- |Tomb Raider Chronicles |- |Tony Hawk's Pro Skater |- |Tony Hawk's Pro Skater 2 |- |Toy Commander |- |''unreleased'' |Toy Racer |- |Toy Story 2 - Buzz Lightyear to the Rescue! |- |TrickStyle |- |The Typing of the Dead |''unreleased'' |- |''unreleased'' |UEFA Dream Soccer |- |Ultimate Fighting Championship |- |Unreal Tournament |- |Urban Chaos |- |Vanishing Point |- |Vigilante 8 |- |Virtua Athlete 2000 |- |Virtua Fighter 3tb |- |Virtua Striker 2 |- |Virtua Tennis |- |Wacky Races |- |Walt Disney World Quest - Magical Racing Tour |- |Wetrix+ |- |''unreleased'' |Who Wants to Be a Millionaire |- |Who Wants to Beat Up a Millionaire |''unreleased'' |- |Wild Metal |- |World Series Baseball 2K1 |''unreleased'' |- |World Series Baseball 2K2 |''unreleased'' |- |Worms Armageddon |- |Worms World Party |- |WWF Attitude |- |WWF Royal Rumble |- |Xtreme Sports |- |Zombie Revenge |} =List of official Western software= {| class="wikitable" ! North American title ! PAL title |- | |Dreamkey Version v1.006 |- | |Dreamkey Version v1.008 |- | |Dreamkey Version 1.5 v1.000 |- | |Dreamkey Version 1.5 v1.001 |- | |Dreamkey Version 1.5 v1.003 |- | |Dreamkey Version 2.0 v1.000 |- | |Dreamkey Version 2.0 v1.001 |- | |Dreamkey Versao 2.0 v1.003 |- | |Dreamkey 3.0 v1.001 |- | |Dreamkey 3.1 v1.000 |- |PlanetWeb Browser v1.124 | |- |PlanetWeb Browser v1.125 | |- |PlanetWeb Browser v2.004 | |- |PlanetWeb Browser with SegaNet v2.100 | |- |PlanetWeb Browser 2.62 a.k.a. v2.613 | |- |PlanetWeb Browser 3.0 |} =List of North American demos= {| class="wikitable" ! Title |- |Airforce Delta Demo Disc |- |Army Men - Sarge's Heroes Demo Disc |- |Dead or Alive 2 Demo CD |- |Demolition Racer - No Exit Demo Disc |- |Gauntlet Legends Demo CD |- |Generator, Vol. 1 |- |Generator, Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 2 |- |Official Sega Dreamcast Magazine Vol. 3 |- |Official Sega Dreamcast Magazine Vol. 4 |- |Official Sega Dreamcast Magazine Vol. 5 |- |Official Sega Dreamcast Magazine Vol. 6 |- |Official Sega Dreamcast Magazine Vol. 7 |- |Official Sega Dreamcast Magazine Vol. 8 |- |Official Sega Dreamcast Magazine Vol. 9 |- |Official Sega Dreamcast Magazine Vol. 10 |- |Official Sega Dreamcast Magazine Vol. 11 |- |Power Stone Retail Demo Disk |- |Ready 2 Rumble Boxing Demo Disc |- |San Francisco RUSH 2049 Demo CD |- |Sonic Adventure 2 - The Trial |- |Super Magnetic Neo Demo CD |- |Tony Hawk's Pro Skater Demo CD |- |Ultimate Fighting Championship Demo Disc |} =List of PAL demos and white-labels= =List of unreleased games= =List of Japanese-exclusive games= =List of Japanese-exclusive demos= =List of Japanese-exclusive software= =List of officially released MIL-CDs= {| class="wikitable" ! Title |- |Checkicco - Checkicco no Miru |- |D no Shokutaku 2 |- |dps - Heart Break Diary |- |Hang the DJ |- |Himitsu - Original Sound Track |- |Kita he - Pure Songs and Pictures |- |Snappers - 09 Chairs |- |Space Channel 5 |} 9a4ab230c01da6ccc3a4bfa8b5be8c510f086efc Atari800DC 0 783 2634 1925 2023-03-03T17:54:53Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Atari800 DC| image=[[File:Atari800DC.png|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]| version=0.78| downloads=Local links: *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78-bin.tar.gz Plainfiles] - 08/17/08 *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78.tar.gz Source] - 08/17/08 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77-bin.tar.gz Plainfiles] - 09/18/07 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77.tar.gz Source] - 09/18/07 | release date=08/17/08| author=[[Captain Skyhawk]]| original=[http://atari800.sourceforge.net/ Atari800]| systems=Atari 400/800/600XL/800XL/etc...| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Atari800 is an emulator for the Atari 8bit machines (400/800/600XL/800XL/etc.) ported to the Dreamcast by [[Captain Skyhawk]] ''(aka Christian Groessler)''. The Dreamcast version uses the [[KallistiOS]] library, and is based on Subversion repository version 560. It can be found at the SourceForge page here: [http://cadcdev.sourceforge.net/ KOS]. The needed BIOS roms can also be found at SourceForge: [http://prdownloads.sf.net/atari800/xf25.zip BIOS Roms]. ==Downloads== * 0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78-bin.tar.gz Plainfiles] - 08/17/08 * 0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78.tar.gz Source] - 08/17/08 * 0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77-bin.tar.gz Plainfiles] - 09/18/07 * 0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77.tar.gz Source] - 09/18/07 ==Links== * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=7566&st=0&sk=t&sd=a DCEmulation Forums] 8d5f5cc0ef515451c2a91a73279e31d4533c4f7d 2635 2634 2023-03-03T17:56:51Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Atari800 DC| image=[[File:Atari800DC.png|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]| version=0.78| downloads=Local downloads: *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78-bin.tar.gz Plainfiles] - 08/17/08 *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78.tar.gz Source] - 08/17/08 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77-bin.tar.gz Plainfiles] - 09/18/07 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77.tar.gz Source] - 09/18/07 | release date=08/17/08| author=[[Captain Skyhawk]]| original=[http://atari800.sourceforge.net/ Atari800]| systems=Atari 400/800/600XL/800XL/etc...| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Atari800 is an emulator for the Atari 8bit machines (400/800/600XL/800XL/etc.) ported to the Dreamcast by [[Captain Skyhawk]] ''(aka Christian Groessler)''. The Dreamcast version uses the [[KallistiOS]] library, and is based on Subversion repository version 560. [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/kos-svn-560-0.78-diffs.gz Diffs are available] for the customizations applied to KallistiOS. The needed BIOS ROMs can also be found at SourceForge: [http://prdownloads.sf.net/atari800/xf25.zip BIOS ROMs]. ==Links== * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=7566&st=0&sk=t&sd=a DCEmulation Forums] 17af8bc15ed4efacb8fd5453172533706c793515 2636 2635 2023-03-03T17:58:53Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Atari800 DC| image=[[File:Atari800DC.png|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]| version=0.78| downloads=Local downloads: *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78-bin.tar.gz Plainfiles] - 08/17/08 *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78.tar.gz Source] - 08/17/08 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77-bin.tar.gz Plainfiles] - 09/18/07 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77.tar.gz Source] - 09/18/07 | release date=08/17/08| author=[[Captain Skyhawk]]| original=[http://atari800.sourceforge.net/ Atari800]| systems=Atari 400/800/600XL/800XL/etc...| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Atari800 is an emulator for the Atari 8-bit machines (400/800/600XL/800XL/etc.) ported to the Dreamcast by [[Captain Skyhawk]] ''(aka Christian Groessler)''. The Dreamcast version uses the [[KallistiOS]] library, and is based on Subversion repository version 560. [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/kos-svn-560-0.78-diffs.gz Diffs are available] for the customizations applied to KallistiOS. The needed BIOS ROMs can also be found at SourceForge: [http://prdownloads.sf.net/atari800/xf25.zip BIOS ROMs]. ==Links== * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=7566&st=0&sk=t&sd=a DCEmulation Forums] 752468bf07a0269516dd717e8c97aaad3775ba4f 2638 2636 2023-03-03T18:09:11Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Atari800 DC| image=[[File:Atari800DC.png|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]| version=0.78| downloads=Local downloads: *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78-bin.tar.gz Plain files] - 08/17/08 *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78.tar.gz Source] - 08/17/08 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77-bin.tar.gz Plain files] - 09/18/07 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77.tar.gz Source] - 09/18/07 *0.75 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.75-bin.tar.gz Source] - 01/17/03 *0.75 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.75.zip Source (alt)] - 01/17/03 *0.75 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.75.tar.gz Plain files] - 01/17/03 *0.72 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.72-bin.zip Plain files] - 09/20/02 | release date=08/17/08| author=[[Captain Skyhawk]]| original=[http://atari800.sourceforge.net/ Atari800]| systems=Atari 400/800/600XL/800XL/etc...| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Atari800 is an emulator for the Atari 8-bit machines (400/800/600XL/800XL/etc.) ported to the Dreamcast by [[Captain Skyhawk]] ''(aka Christian Groessler)''. The Dreamcast version uses the [[KallistiOS]] library, and is based on Subversion repository version 560. [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/kos-svn-560-0.78-diffs.gz Diffs are available] for the customizations applied to KallistiOS. The needed BIOS ROMs can also be found at SourceForge: [http://prdownloads.sf.net/atari800/xf25.zip BIOS ROMs]. ==Links== * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=7566&st=0&sk=t&sd=a DCEmulation Forums] a9e9410ee880c1beaedc7cd21693f13504c0276c (D)cs2600 0 784 2637 1926 2023-03-03T18:00:53Z Unknown user 0 /* Known bugs */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=(D)cs2600| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=public beta 13/09/01| downloads=[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600dj.zip DiscJuggler]<br/>[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600nero.zip Nero]<br/>[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600plain.zip Plain Files]<br/>| release date=09/13/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://www.atarihq.com/danb/emulation.shtml#myemulators Virtual VCS]<br/>by Dan Boris| systems=Atari 2600 VCS| NTSCVGAPAL=NTSC| firstversion=[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600plain.zip public beta 13/09/01]<br/>09/13/01| best=No. We recommend<br/>[[Stella DC]]| isactive=No }} (D)cs2600 was one of the first emulators ported to the Sega Dreamcast. It is now discontinued, and [[Stella DC]] is now the better of the two Atari 2600 VCS emulators available. =Known bugs= *Keypad emulation doesn't work right *Hangs up/reboots when a unsupported game is started *ROM selection screen gets messed up after playing a few games =Controls= '''Graphical User Interface - Controls'''<br/> *Press UP/DOWN to choose a menu item and A to activate it. *Press B to leave a menu. '''Rom Selection Screen'''<br/> *Press A to start a game. *Press X to see which Bank Switching Scheme will be used if the Bank Switching *Scheme option is set to "auto". *Press L+R+START to leave a game. *Press Left or Right to move a page forward/backward *Press L or R to move a 5 pages forward/backward '''ATARI2600 Buttons'''<br/> *X - Toggle BW/Color Mode *L - Reset *R - Select *START+A - P0 Pro *START+B - P1 Pro *START+X - P0 Amateur *START+Y - P1 Amateur '''ATARI2600 JOYPAD'''<br/> *A - FIRE *Digital Pad - Move '''ATARI2600 Trackball'''<br/> *A - FIRE *Analogue Stick - Move '''ATARI2600 Keypad'''<br/> (a Dreamcast Keyboard is required to use the ATARI2600 Keypad)<br/> *P0 - Keys: **1,2,3,Q,W,E,A,S,D,Z,X,C *P1 - Keys: **5,6,7,T,Y,U,G,H,J,B,N,M d9612d354d6f0eca4bc87c8b5b46b3432c545b68 2639 2637 2023-03-03T18:12:44Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=(D)cs2600| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=public beta 13/09/01| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dcs2600/dcs2600dj.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/dcs2600/dcs2600nero.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/dcs2600/dcs2600plain.zip Plain Files]<br/>| release date=09/13/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://www.atarihq.com/danb/emulation.shtml#myemulators Virtual VCS]<br/>by Dan Boris| systems=Atari 2600 VCS| NTSCVGAPAL=NTSC| firstversion=[http://www.dcemulation.com/files/emulators/dcs2600/dcs2600plain.zip public beta 13/09/01]<br/>09/13/01| best=No. We recommend<br/>[[Stella DC]]| isactive=No }} (D)cs2600 was one of the first emulators ported to the Sega Dreamcast. It is now discontinued, and [[Stella DC]] is now the better of the two Atari 2600 VCS emulators available. =Known bugs= *Keypad emulation doesn't work right *Hangs up/reboots when a unsupported game is started *ROM selection screen gets messed up after playing a few games =Controls= '''Graphical User Interface - Controls'''<br/> *Press UP/DOWN to choose a menu item and A to activate it. *Press B to leave a menu. '''Rom Selection Screen'''<br/> *Press A to start a game. *Press X to see which Bank Switching Scheme will be used if the Bank Switching *Scheme option is set to "auto". *Press L+R+START to leave a game. *Press Left or Right to move a page forward/backward *Press L or R to move a 5 pages forward/backward '''ATARI2600 Buttons'''<br/> *X - Toggle BW/Color Mode *L - Reset *R - Select *START+A - P0 Pro *START+B - P1 Pro *START+X - P0 Amateur *START+Y - P1 Amateur '''ATARI2600 JOYPAD'''<br/> *A - FIRE *Digital Pad - Move '''ATARI2600 Trackball'''<br/> *A - FIRE *Analogue Stick - Move '''ATARI2600 Keypad'''<br/> (a Dreamcast Keyboard is required to use the ATARI2600 Keypad)<br/> *P0 - Keys: **1,2,3,Q,W,E,A,S,D,Z,X,C *P1 - Keys: **5,6,7,T,Y,U,G,H,J,B,N,M df748d89a68ef0c6a28dbb2fa03644df7dc4b062 Stella DC 0 786 2640 1928 2023-03-03T18:20:50Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCStella| image=[[Image:Stella.jpg|250px]]| homepage=[http://svolli.org/software/dcstella/ Homepage]| version=V0.2F| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/stelladc/stella02f.zip 02f] - 4/22/04 *[https://files.dcemulation.org/software/dreamcast/emulators/stelladc/stella02e.zip 02e] - 4/30/03 *[https://files.dcemulation.org/software/dreamcast/emulators/stelladc/stella02e-pd-nero.zip 02e Nero PD] - 4/30/03 *[https://files.dcemulation.org/software/dreamcast/emulators/stelladc/stella02e-qb-nero.zip 02e Nero QB] - 4/30/03 *[https://files.dcemulation.org/software/dreamcast/emulators/stelladc/dcstella.zip Unknown Early Ver] - 10/16/02 *[https://files.dcemulation.org/software/dreamcast/emulators/stelladc/stella_for_dc.zip Unknown Early Ver] - 12/9/01 | release date=04/25/04| author=[[SvOlli]]| original=Bradford Mott<br/>(Stella Atari 2600 VCS)| systems=Atari 2600 VCS| best=Yes.| isactive=No }} StellaDC is the best Atari 2600 emulator for Dreamcast. It is based on Stella and was ported by German Dreamcast developer [[SvOlli]]. There's sound while emulating games and DCStella runs pretty fast. Unfortunately there are problems with many PAL games. =Controls= '''In the menu:'''<br/> *Up/Down - Highlight a game *Left/Right - Go to next page of games *A - Load game '''During game:'''<br/> *Directional pad or joystick - Move *A - Fire *Y - Toggle Difficulty A/B *B - Toggle Black and White/Color *X - Select game *Start - Reset game *L+R - Exit to menu *B, X, Start, and L+R only work on the first controller [[Category:Emulator]] 64156f0535e22916b15845effa7780304d9c2314 DC7800 0 787 2641 1929 2023-03-03T18:23:55Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/a7800new.rar Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/dc7800.zip Plain Files] v1<br/> *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/DCA7800v2_CG.sbi SBI] v1 <br/>| release date=Unknown| last update=16/02/04| author=Ian Micheal| original=N/A| systems=Atari 2600 / Atari 7800| best=Unknown| isactive=No }} Developer: Ian Micheal<br> Updated: 16-02-04<br> Version: v3<br> An Atari 2600/7800 emulator. [[Category:Emulator]] c9696ff2ecb5a6742cf201bdf5de086233bc0d4b 2642 2641 2023-03-03T18:26:50Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/a7800new.rar Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/dc7800.zip Plain Files] v1<br/> *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/DCA7800v2_CG.sbi SBI] v1 <br/>| release date=Unknown| last update=16/02/04| author=Ian Micheal| original=N/A| systems=Atari 2600 / Atari 7800| best=Unknown| isactive=No }} DC7800 is a an Atari 2600/7800 emulator compiled by [[Ian MIcheal]] based on [[Warmtoe]]'s work on MESS and MAME. Its last version was v3, released on February 16, 2004. [[Category:Emulator]] 00aed4aea3da59894adf5502b6a070550a1ae770 2643 2642 2023-03-03T18:27:23Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/a7800new.rar Plain Files Ver?] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/dc7800.zip Plain Files Ver?] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/DCA7800v2_CG.sbi SBI Ver?] | release date=Unknown| last update=16/02/04| author=Ian Micheal| original=N/A| systems=Atari 2600 / Atari 7800| best=Unknown| isactive=No }} DC7800 is a an Atari 2600/7800 emulator compiled by [[Ian MIcheal]] based on [[Warmtoe]]'s work on MESS and MAME. Its last version was v3, released on February 16, 2004. [[Category:Emulator]] 6347a0ccb964dd84fa4cfee053d0338bd7696bd1 (D)Colem 0 791 2644 1934 2023-03-03T18:29:00Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=[D]Colem| image=[[File:Dcolem4.jpg|center|250px]]| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=0.99| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/d99sb.zip DiscJuggler]*[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/d99p.zip Plain Files] | release date=06/18/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://fms.komkon.org/ColEm/ ColEm]<br/>by Marat Fayzullin| systems=ColecoVision| firstversion=[http://www.dcemulation.com/files/emulators/dcolem/dcolemwhatever.zip FIXME]<br/>| best=Yes| isactive=No| refreshrate=50Hz }} [D]Colem is the only ColecoVision emulator on the Sega Dreamcast. It is based on [http://fms.komkon.org/ColEm/ ColEm] was ported to Dreamcast by Austrian Dreamcast developer [[Gonzo]]. [D]Colem is reported to run fullscreen with sound. =Known bugs= *8 and 9 keys aren't properly emulated *Video flickering on 60Hz displays [[Category:Emulator]] f424d0e0391667da31cf908e5fc3a43a51cdcb09 2645 2644 2023-03-03T18:29:09Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=[D]Colem| image=[[File:Dcolem4.jpg|center|250px]]| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=0.99| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/d99sb.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/d99p.zip Plain Files] | release date=06/18/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://fms.komkon.org/ColEm/ ColEm]<br/>by Marat Fayzullin| systems=ColecoVision| firstversion=[http://www.dcemulation.com/files/emulators/dcolem/dcolemwhatever.zip FIXME]<br/>| best=Yes| isactive=No| refreshrate=50Hz }} [D]Colem is the only ColecoVision emulator on the Sega Dreamcast. It is based on [http://fms.komkon.org/ColEm/ ColEm] was ported to Dreamcast by Austrian Dreamcast developer [[Gonzo]]. [D]Colem is reported to run fullscreen with sound. =Known bugs= *8 and 9 keys aren't properly emulated *Video flickering on 60Hz displays [[Category:Emulator]] cdb35cc40d81bfc3286479485fb745ad5f0edf30 CrabEmu 0 789 2646 1931 2023-03-03T18:33:21Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=CrabEmu| image=[[Image:crabemu.png]]| homepage=[http://crabemu.sourceforge.net Homepage]| version=0.2.0| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/crabemu/CrabEmu-0.2.0-dc.tar.bz2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/crabemu/CrabEmu-0.2.0.tar.bz2 Source Code]| release date=2/27/2013| author=Lawrence Sebald<br/>([[BlueCrab]])| original=[http://crabemu.sourceforge.net CrabEmu]<br/>by Lawrence Sebald ([[BlueCrab]])| systems=Sega Master System<br />Game Gear<br />SG-1000<br />ColecoVision (SVN r107+ or 0.2.0 and later)<br />NES (SVN r166+ or 0.2.0 and later)<br />CHIP-8 (SVN r249 or later)| best=Maybe?| refreshrate=50/60Hz| isactive=Yes }} CrabEmu is a port of the emulator of the same name originally for Mac OS X. It currently emulates Sega Master System, Game Gear, SG-1000, ColecoVision and the NES. Other consoles are planned for future versions. Development is mainly focused on 8-bit Sega consoles. The code for the other consoles (especially the NES) is not as mature and thus is not nearly as complete. =Controls= '''Rom Selection Screen'''<br/> *Press A to start a game. *Hold Left Trigger and press A to run the game in a stretched full-screen mode. *Up/Down on Directional Pad - move up/down one rom in the menu. *Left/Right on Directional Pad - move up/down a page of roms in the menu. '''SMS/Game Gear/SG-1000 In-Game Buttons'''<br/> *A - Button 1 *B - Button 2 *START - Game Gear Start Button *Directional Pad - Directional Pad *Left Trigger + Y - Return to Rom Select Screen *Right Trigger + Y - Save SRAM to VMU in slot A1. '''ColecoVision In-Game Buttons'''<br /> *Joystick - ColecoVision Joystick *A - Left Action Button *B - Right Action Button *X - Button 1 *Y - Button 2 *DPad Up - Button 3 *DPad Down - Button 4 *DPad Left - Button 5 *DPad Right - Button 6 *Left Trigger + A - Button 7 *Left Trigger + B - Button 8 *Left Trigger + DPad Up - Button 9 *Left Trigger + DPad Down - Button * *Left Trigger + DPad Left - Button 0 *Left Trigger + DPad Right - Button # '''NES In-Game Buttons'''<br/> *A - B *B - A *START - Start *B - Select *Directional Pad - Directional Pad 0c3026acb2d8216b62b4f583d746b5ed5409da07 Odd-DC 0 792 2647 1935 2023-03-03T18:35:54Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=OddDC| image=no image| homepage=[http://dcolem.emuunlim.com Homepage]| version=Early Beta| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/odddc/oddDCDJ.zip Disk Juggler] *[https://files.dcemulation.org/software/dreamcast/emulators/odddc/oddDC.zip Plain Files] | release date=09/03/01| author=[[Gonzo]]| original=O2EM| systems=Odyssey2 (G7000 in Europe)| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} oddDC is a port of O2EM 0.65, an Odyssey2 (G7000 in Europe) emulator written by Dan Boris(dboris@erols.com). To learn more about the emulator itself check /docs/o2em.txt. Latest Status: * 2 player support [[category:Emulator]] 935585aa36ae74b41e24868e10438a598d6b24c1 IntelliMESS 0 793 2648 1936 2023-03-03T18:38:59Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=IntelliMESS| image=No Screenshot available| homepage=Unknown| version=V2| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/intellimess/intvdc2.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/intellimess/InTVDC2_CG.sbi Selfboot Inducer] | release date=Unknown| last update=Unknown| author=Ian Micheal| original=ice88's M.E.S.S.| systems=Intellivision| best=Unknown| isactive=Unknown }} Developer: Ian Micheal Updated: 2003 An Intellivision emulator based on ice88's M.E.S.S. port. It doesn't have full controller support but does run some games that don't require 16 buttons to play. [https://files.dcemulation.org/software/dreamcast/emulators/intellimess/intv.txt Intellivision M.E.S.S. Final Readme] [[Category:Emulator]] 68afbe0a1c9d230cce56bd43106cea0f74b7da2d Vectrex MESS 0 794 2649 1937 2023-03-03T18:41:22Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Vectrex MESS| image=No Screenshot available| homepage=Unknown| version=Unknown| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/vectrexmess/Vectrex.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/vectrexmess/VectrexCDI.zip Discjuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/vectrexmess/DCVectrex_072_CG.sbi Selfboot Inducer] | release date=Unknown| author=Ian Micheal| original=ice88's M.E.S.S| systems=Vectrex| best=Unknown| isactive=Unknown }} Developer: Ian Micheal Updated: 2003 A Vectrex emulator based on ice88's M.E.S.S port. It is not compatible with light pen & 3D imager games. [[category:emulator]] 268763447c0d47e0608d87dc8ec04bee2bf07fe0 PCECast 0 796 2650 1940 2023-03-03T18:43:07Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=PCEcast| image=[[File:Pcecast.jpg]]| homepage=Unknown| version=Unknown| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/pcecast/pcecast.zip Plain Files] - 06/01/07| release date=Unknown| author=[[LTK]]| original=N/A| systems=PC Engine / TurboGrfx16| best=Unknown| isactive=Unknown }} PCECast is a PC Engine / TurboGrfx16 emulator for Dreamcast by [[LTK]] a.k.a Uguru. LTK is known for Dreamcast projects like [[HOTA]], [[MSXCast]], [[CPCast]] and others. ==Features== * Almost full speed * Games in PCE, ISO, HCD, TOC, NEC format supported * CD-ROM Games are suported as ISO+WAV (HCD, TOC, NEC) * Sound & CD Sound * .pce ROMs can be zipped * Analog stick support * Savestate with mini-screenshot * 6 button pad support * FPS counter ==Instructions== You can add your ROMs anywhere on the disc: Put .pce ROMs e.g. in /PCE/ folder, .iso files in /ISO/. Be sure to have syscard.pce in root! [[Category:Emulator]] 245b838bdc6ec2b5c39ce772df7012461355a22a Dream Engine 0 797 2651 1941 2023-03-03T18:45:36Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamEngine| image=| homepage=[http://www.billnagel.com/ Homepage]| version=V0.01| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/dengine.zip Plain Files| release date=Unknown| last update=07-28-02| author=Bill Nagel| original=N/A| systems=TG-16/Pc Engine emulator| best=Unknown| isactive=Unknown }}Developer: [http://www.billnagel.com/ Bill Nagel] A TG-16/PC Engine emulator. Speed varies but many games run at (or near) full speed. Currently no sound. [https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/DreamEngine0.01.txt Dream Engine 0.01 README file] [[Category:Emulator]] f58b1a24b10a646567a3a4da367fb39c29a4cfc4 2652 2651 2023-03-03T18:45:45Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamEngine| image=| homepage=[http://www.billnagel.com/ Homepage]| version=V0.01| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/dengine.zip Plain Files]| release date=Unknown| last update=07-28-02| author=Bill Nagel| original=N/A| systems=TG-16/Pc Engine emulator| best=Unknown| isactive=Unknown }}Developer: [http://www.billnagel.com/ Bill Nagel] A TG-16/PC Engine emulator. Speed varies but many games run at (or near) full speed. Currently no sound. [https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/DreamEngine0.01.txt Dream Engine 0.01 README file] [[Category:Emulator]] 471fe624b17306263658dbf90cdacd5748a16aa2 2653 2652 2023-03-03T18:46:00Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamEngine| image=| homepage=[http://www.billnagel.com/ Homepage]| version=V0.01| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/dengine.zip Plain Files]| release date=Unknown| last update=07-28-02| author=Bill Nagel| original=N/A| systems=TG-16/PC Engine| best=Unknown| isactive=Unknown }}Developer: [http://www.billnagel.com/ Bill Nagel] A TG-16/PC Engine emulator. Speed varies but many games run at (or near) full speed. Currently no sound. [https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/DreamEngine0.01.txt Dream Engine 0.01 README file] [[Category:Emulator]] 7304d3a089eb4ff05d91569372bdd558e51c0cc5 DCNin64 0 799 2654 1943 2023-03-03T18:53:41Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCNin 64| image=No Screenshot Available| homepage=[http://gpf.dcemu.co.uk/dcnin64.shtml Homepage]| version=Alpha| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dcnin64/dcnin64.zip Plain Files]| release date=?| author=[[GPF]]| original=Nincest 64| systems=Nintendo 64| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} ==DCNin64== DCNin64 was the first Nintendo 64 emulator for the Dreamcast. It is based on Nincest 64 and was ported by [[GPF]]. 870b80d315d16e4a45e9f683703e2d1f6fcdd3b2 2655 2654 2023-03-03T18:53:51Z Unknown user 0 /* DCNin64 */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCNin 64| image=No Screenshot Available| homepage=[http://gpf.dcemu.co.uk/dcnin64.shtml Homepage]| version=Alpha| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dcnin64/dcnin64.zip Plain Files]| release date=?| author=[[GPF]]| original=Nincest 64| systems=Nintendo 64| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} DCNin64 was the first Nintendo 64 emulator for the Dreamcast. It is based on Nincest 64 and was ported by [[GPF]]. ac96c1b143daaccc61aadd7612af1eb243c91faa DaedalusDC 0 801 2656 1945 2023-03-03T19:04:48Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Daedalus| image=[[File:daedalusdc.png|center|250px]]| homepage=[http://www.maturion.de/daedalus Homepage]| version=R8| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/daedalusdc/DaedalusDC.rar Plain Files]| release date=01/06/2008| author=[[Simpson474]]| original=Daedalus<br/>([[StrmnNrmn]])| systems=Nintendo 64| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Daedalus is a Nintendo 64 emulator by [[StrmnNrmn]]. The project was started in 1998 and the first release was in 2000. In early 2001 Daedalus got hosted by the popular Dreamcast website [http://www.boob.co.uk B00B! Dreamcast Research]. During the same time, other developers became involved in the development of Daedalus, most notably [[CyRUS64]] who is a well known face in the Dreamcast scene. StrmnNrmn also ported Daedalus to the Xbox but after his port got leaked he decided not to release it. When [[CyRUS64]] somehow left the Dreamcast and console scene in general (around june 2003) [[StrmnNrmn]] stopped development of his emulator. In early 2006 StrmnNrmn picked up Daedalus again and ported it to the Sony PSP. Until late 2007 StrmnNrmn was actively developing the PSP port of Daedalus but then he announced he'd stopped work on DaedalusPSP and he stated that he'd port Daedalus to an "unkown" platform. In late 2007 a German Dreamcast developer named [[Simpson474]] ported Daedalus to the Dreamcast and released it in January 2008. The Dreamcast version currently runs with about 10 fps in Super Mario 64. DaedalusDC consists of two port of Daedalus. The one is based on the PC version of Daedalus (from 2001), the other one is based on the PSP port (from 2006-2007). While the one based on the PC version offers higher compatibility, the one based on the PSP port can be considered faster. There are several YouTube videos showing DaedalusDC running on real hardware. Although, it is extremly slow, the Dreamcast port of Daedalus is reported to be compatible with a number of several popular games, including Mario Kart 64, Super Mario 64 and Zelda - Ocarina of Time. The Dreamcast version can be downloaded from [http://www.rapidshare.com/files/81713061/DaedalusDC.rar.html Rapidshare] or [http://www.maturion.de/dreamcast/DaedalusDC.rar Maturion.de]. Below is the video [[Simpson474]] published on YouTube: *http://www.youtube.com/watch?v=1eEUmZtRFME Other videos showing DaedalusDC in action: *[http://www.youtube.com/watch?v=-Lgy05-bi1c DaedalusDC running Mario Kart] *[http://www.youtube.com/watch?v=jm3k9pXzWAk DaedalusDC running Zelda -Ocarina of Time] ==Links== *[http://strmnnrmn.blogspot.com StrmnNrmn's Blog] *[http://daedalus.boob.co.uk| Old Daedalus site @ B00B] *[http://www.maturion.de/daedalus Daedalus site (restored) @ Maturion.de] [[Category:Emulator]] a04e2a1b86c5291ad5fe5688a6b760320f4216dc 2657 2656 2023-03-03T19:05:08Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Daedalus| image=[[File:daedalusdc.png|center|250px]]| homepage=[http://www.maturion.de/daedalus Homepage]| version=R8| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/daedalusdc/DaedalusDC.rar Plain Files]| release date=01/06/2008| author=[[Simpson474]]| original=Daedalus<br/>([[StrmnNrmn]])| systems=Nintendo 64| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Daedalus is a Nintendo 64 emulator by [[StrmnNrmn]]. The project was started in 1998 and the first release was in 2000. In early 2001 Daedalus got hosted by the popular Dreamcast website [http://www.boob.co.uk B00B! Dreamcast Research]. During the same time, other developers became involved in the development of Daedalus, most notably [[CyRUS64]] who is a well known face in the Dreamcast scene. StrmnNrmn also ported Daedalus to the Xbox but after his port got leaked he decided not to release it. When [[CyRUS64]] somehow left the Dreamcast and console scene in general (around june 2003) [[StrmnNrmn]] stopped development of his emulator. In early 2006 StrmnNrmn picked up Daedalus again and ported it to the Sony PSP. Until late 2007 StrmnNrmn was actively developing the PSP port of Daedalus but then he announced he'd stopped work on DaedalusPSP and he stated that he'd port Daedalus to an "unkown" platform. In late 2007 a German Dreamcast developer named [[Simpson474]] ported Daedalus to the Dreamcast and released it in January 2008. The Dreamcast version currently runs with about 10 fps in Super Mario 64. DaedalusDC consists of two port of Daedalus. The one is based on the PC version of Daedalus (from 2001), the other one is based on the PSP port (from 2006-2007). While the one based on the PC version offers higher compatibility, the one based on the PSP port can be considered faster. There are several YouTube videos showing DaedalusDC running on real hardware. Although, it is extremly slow, the Dreamcast port of Daedalus is reported to be compatible with a number of several popular games, including Mario Kart 64, Super Mario 64 and Zelda - Ocarina of Time. The Dreamcast version can be downloaded from [http://www.rapidshare.com/files/81713061/DaedalusDC.rar.html Rapidshare] or [http://www.maturion.de/dreamcast/DaedalusDC.rar Maturion.de]. Below is the video [[Simpson474]] published on YouTube: *http://www.youtube.com/watch?v=1eEUmZtRFME Other videos showing DaedalusDC in action: *[http://www.youtube.com/watch?v=-Lgy05-bi1c DaedalusDC running Mario Kart] *[http://www.youtube.com/watch?v=jm3k9pXzWAk DaedalusDC running Zelda -Ocarina of Time] ==Links== *[http://strmnnrmn.blogspot.com StrmnNrmn's Blog] *[http://daedalus.boob.co.uk Old Daedalus site @ B00B] *[http://www.maturion.de/daedalus Daedalus site (restored) @ Maturion.de] [[Category:Emulator]] 15eff8ef59fcbb75c8da7e87ffb72ec859bb9701 NesterDC SE 0 806 2658 1951 2023-03-03T19:10:20Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC SE| image=[[Image:nesterdcse.gif]]<br />[[File:nesterdcsescreen.png|center|250px]]| homepage=[http://www.sch3rz0.com/nesterdcse/ Homepage]| version=1.1 (Unofficial)| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdcse/NesterSEv11_plain_files.rar 1.1 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdcse/NesterSEv11_cdi.rar 1.1 DiscJuggler] (w\ Homebrew) *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdcse/NesterDCSE_2005-12-10.zip 1.0 Plain Files] - 12/9/05 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdcse/NesterDCSE-src_2005-12-24.zip 1.0 Source] - 12/24/05 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdcse/NesterDCSE-KOS-src_2005-12-24.zip 1.0 KOS Source] - 12/24/05 | release date=December 9, 2008| author=[[Scherzo]]; 1.1 by<br>[[Christuserloeser]]| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester]| systems=NES, Famicom| best=Yes| refreshrate=50Hz/60Hz| isactive=No }} NesterDC SE is an highly polish and updated version of NesterDC 7.1, an already splendid NES emulator, under development by Scherzo. In late 2008 (December) [[Christuserloeser]] released an "Unofficial" update to NesterDC SE that makes changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. These changes were done via JavaScript so if the source code is what you are looking for grab 1.0's source below. Official DCEmulation Forum Threads:<br> [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=74417 NesterDC SE 1.0]<br> [http://dcemulation.org/phpBB/viewtopic.php?f=72&t=98192 NesterDC SE 1.1 (Unofficial Build)] '''Features: *Greatly Improved Compatibility (VS ROMs correctly supported) *An NSF player *Controller buttons can be remapped *Stereo separation of each NES sound channel *Full screen stretched and pixel-for-pixel video modes *Game-Genie implementation *Multiple save state slots (with the first slot being backwards compatible) *Supports Zipped ROMs *CD Builder grabs Manual & Cartridge, Game-Genie and more from master list *Various game related images by which you can use to browse the ROM library *Favorite Game list *Ability to enter your own personal notes about a game and save these notes on your VMU ==Master Library== If using the NesterDC SE ''CD Builder'' for version 1.0, replace the default URL with one of the following mirrors. *Local, still works in 2023: http://nesterdcse.dcemulation.org/master_library/ [[Category:Emulator]] dba38facadce4063a155c57cc7aae3e85d01dc72 NesterDC 0 808 2659 1953 2023-03-03T19:12:07Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Older Versions== * 7.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-7.0.zip Plain Files] * 7.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-7.0.tar.gz Source Code] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/NesterDC.exe Best Damned Tutorial] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.zip Plain Files] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.tar.gz Source Code] * 5.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-5.0.tar.gz Source Code] - 12/03/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_src.zip Source Code] - 6/03/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1.zip Plain Files] - 2/20/01 257aa484580508235169402cda7ef5ba4056ade5 2660 2659 2023-03-03T19:16:11Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC7.1DJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7.1Nero.zip Nero] | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Older Versions== * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.zip Plain Files] * 7.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-7.0.tar.gz Source Code] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/NesterDC.exe Best Damned Tutorial] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.zip Plain Files] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.tar.gz Source Code] * 5.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-5.0.tar.gz Source Code] - 12/03/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_src.zip Source Code] - 6/03/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1.zip Plain Files] - 2/20/01 b3830ff4e9385573e6d1922c60ad2c995e24cedb 2661 2660 2023-03-03T19:24:06Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.tar.gz Source Code] 7.1 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.1-sdl.tar.gz Source Code] 7.1.1 (SDL) *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC7.1DJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7.1Nero.zip Nero] | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Historical Files== * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.zip Plain Files] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.tar.gz Source Code] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC.exe Best Damned Tutorial (Windows)] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-1ST_READ.BIN.zip 1ST_READ.BIN] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-PAL-1ST_READ.BIN.zip 1ST_READ.BIN] (PAL) * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.zip Plain Files] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0.tar.gz Source Code] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1.tar.gz Source Code] * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-v3_src.zip Source Code] - 6/03/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc_v1.zip Plain Files] - 2/20/01 0c0b0e8a7329640986592b2e87365d30ab514154 2662 2661 2023-03-03T19:31:13Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.tar.gz Source Code] 7.1 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.1-sdl.tar.gz Source Code] 7.1.1 (SDL) *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC7.1DJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7.1Nero.zip Nero] | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Historical Files== * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.zip Plain Files] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.tar.gz Source Code] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC.exe Best Damned Tutorial (Windows)] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-1ST_READ.BIN.zip 1ST_READ.BIN] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-PAL-1ST_READ.BIN.zip 1ST_READ.BIN] (PAL) * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0.tar.gz Source Code] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1-1ST_READ.BIN.zip 1ST_READ.BIN] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1.tar.gz Source Code] * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_src.zip Source Code] - 6/03/01 * 3.0t3 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-3.0t3.zip Plain Files] * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1.zip Plain Files] - 2/20/01 34733af936d33daca0d3f49a2fc8c896c0a6d577 FrNES 0 817 2663 1962 2023-03-03T19:46:54Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-DJImage.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-NeroImage.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-RawFiles.zip Plain Files] | release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} == About == FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements == Older versions == *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b2-RawFiles.zip 0.60b2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b-RawFiles.zip 0.60b Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] =Screen Shots= [[Image:Frnes1.jpg|center|250px]] [[Image:Frnes2.jpg|center|250px]] [[Image:Frnes3.jpg|center|250px]] [[Image:Frnes4.jpg|center|250px]] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] b2b361fc362dc9376ff56ffd134dd298e4e8ba42 2664 2663 2023-03-03T19:48:03Z Unknown user 0 /* Older versions */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-DJImage.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-NeroImage.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-RawFiles.zip Plain Files] | release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} == About == FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements == Older versions == *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b2-RawFiles.zip 0.60b2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b-RawFiles.zip 0.60b Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/frnes4pl.zip 0.40? Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] =Screen Shots= [[Image:Frnes1.jpg|center|250px]] [[Image:Frnes2.jpg|center|250px]] [[Image:Frnes3.jpg|center|250px]] [[Image:Frnes4.jpg|center|250px]] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] e4e949566c0d068549b74364e6959ab07d157a9c 2665 2664 2023-03-03T19:48:50Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-DJImage.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-NeroImage.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-RawFiles.zip Plain Files] | release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements [[Image:Frnes1.jpg|center|250px]][[Image:Frnes2.jpg|center|250px]][[Image:Frnes3.jpg|center|250px]][[Image:Frnes4.jpg|center|250px]] == Older versions == *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b2-RawFiles.zip 0.60b2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b-RawFiles.zip 0.60b Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/frnes4pl.zip 0.40? Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] 62b7fb9c89ae1b0cbfe7eb04d27ee066841389f7 2666 2665 2023-03-03T19:49:07Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-DJImage.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-NeroImage.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-RawFiles.zip Plain Files] | release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements [[Image:Frnes1.jpg|center|250px]] [[Image:Frnes2.jpg|center|250px]] [[Image:Frnes3.jpg|center|250px]] [[Image:Frnes4.jpg|center|250px]] == Older versions == *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b2-RawFiles.zip 0.60b2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b-RawFiles.zip 0.60b Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/frnes4pl.zip 0.40? Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] 7c5b8f0dbdd738274e9cf0ff9d3e803217afe29f 2667 2666 2023-03-03T19:51:05Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-DJImage.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-NeroImage.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-RawFiles.zip Plain Files] | release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements ==Screenshots== <gallery> Image:Frnes1.jpg|center|250px| Image:Frnes2.jpg|center|250px| Image:Frnes3.jpg|center|250px| Image:Frnes4.jpg|center|250px| </gallery> ==Older versions== *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b2-RawFiles.zip 0.60b2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b-RawFiles.zip 0.60b Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/frnes4pl.zip 0.40? Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] 98f7648a870f33394260e2d5fce71e0afd81d5cf TuxNES-DC 0 818 2668 1963 2023-03-03T19:57:13Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=TuxNES-DC| homepage=[http://3e8.org/ Homepage]| version=0.2| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/tuxnesdc/tuxnes-dc-0.2-bin.tgz Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/tuxnesdc/tuxnes-dc-0.2.tgz Source Code] *[https://files.dcemulation.org/software/dreamcast/emulators/tuxnesdc/TuxNES-DC-0.2-CDI.zip 0.2 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/tuxnesdc/TuxNES-DC-0.2-NRG.zip 0.2 Nero] | release date=2/27/02| author=[[Jim Ursetto]]| original=[http://tuxnes.sourceforge.net/ TuxNES] by<br/>Mike Melanson| systems=NES| best=No.| isactive=No. }} A working NES emulator; working, in the sense that it plays most nes games at 30fps with sound or 50-60fps without. And the source code has been made public. Status: Emulation aspect: Almost all games work at 30FPS with sound. In fact, the renderer is artificially locked to 30FPS (frameskip = 1). Without sound, I benchmarked between 50-60 FPS on most games. You can disable sound, vsync and frameskip to achieve these speeds. Sound works well, but is subject to some artifacts. If game speed drops below 30FPS, sound will break up. Save games are implemented, but you need dcload and a PC to take advantage. I.e., vmu saving is not supported. Full sourcecode released. =Older Versions= *[https://files.dcemulation.org/software/dreamcast/emulators/tuxnesdc/tuxnes-dc-0.1-bin.zip 0.1 Plain Files] - 12/14/01 *[https://files.dcemulation.org/software/dreamcast/emulators/tuxnesdc/tuxnes-dc-0.1.tgz 0.1 Source Code] - 12/14/01 cac19032c5f735a0e7e8510bfa9de4910d3b589b Gleam! 0 820 2669 1966 2023-03-03T20:08:19Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=gleam!| image=[[File:Gleam.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/gleam/ Homepage]| version=103000| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/gleam/gleamcdi.zip Disc Juggler ] *[https://files.dcemulation.org/software/dreamcast/emulators/gleam/gleamnrg.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/gleam/gleamez.zip Easy CD] | release date=01/06/2000| author=[[Chuck Mason]]| original=Many<br/>| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No. }} '''gleam!''' was the first emulator ever to be released for the Dreamcast. It was created by [[Chuck Mason]]. It isn't based on anything, it was made from scratch and has 3 different CPU cores. gleam! is a working NES emulator; working, in the sense that it is compatible with most games. However, it's been discontinued. Although its source code has been made public, the project has never been picked up again by any other developer. Today, emulators such as [[NesterDC]] and [[NesterDC SE]] have by far surpassed gleam! in terms of speed and compatibility and should therefore be used. ==Features== * asm cpu core * More compatibility (mappers 4, 7, etc. are partially supported). * Minor graphics fixes. * 2 Player support! * Now supports sound * Fully interactive setup * Option menu with frame skip * FULL SCREEN option. * Save and Load Support. [[Category:Emulator]] 4abf5fecfd3b757f75ddb70a00da23bf49891e1f DarcDC 0 821 2670 1967 2023-03-03T20:09:58Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DarcDC| image=No screenshot available| homepage=Unknown| version=Beta 1| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/darcdc/DarcDC.zip Plain Files]<br/>| release date=Unknown| author=ss_teven| original=Many| systems= PC-Engine/TurboGrafx-16,<br /> NES,<br /> Sega Master System,<br /> Sega SG-1000/3000<br /> Sega GameGear<br /> | best=No| isactive=No }} Developer: ss_teven Version: Beta 1 Last Updated: December 21, 2001 A port of DarcNES, an emulator that will allow you to play PC-Engine/TurboGrafx-16, NES, Sega Master System, Sega SG-1000/3000 & Sega GameGear games. [[category:emulator]] 18d905491fa0ce2576ab15a1dc650cac0cc7ee32 2671 2670 2023-03-03T20:10:56Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DarcDC| image=No screenshot available| homepage=Unknown| version=Beta 1| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/darcdc/DarcDC.zip Plain Files]<br/>| release date=Unknown| author=ss_teven| original=Many| systems= PC-Engine/TurboGrafx-16,<br /> NES,<br /> Sega Master System,<br /> Sega SG-1000/3000<br /> Sega GameGear<br /> | best=No| isactive=No }} DarcDC is a port of DarcNES by ss_teven. Its last version was beta 1, released on December 21, 2001. It supports playing PC-Engine/TurboGrafx-16, NES, Sega Master System, Sega SG-1000/3000 & Sega GameGear games. [[category:emulator]] 8f2bbf3db591ad1aa2106413047c3205362bb675 Super Famicast 0 828 2672 1975 2023-03-03T20:17:53Z Unknown user 0 /* Super Famicast */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Super Famicast| image=[[Image:superfamicast.jpg|center|250px]]| homepage=[http://archives.dcemulation.org/www.superfamicast.com/ Homepage]| version=2.0| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V1(DJ).zip DiscJuggler(V1)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V2(DJ).zip DiscJuggler (V2)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V1(Nero).zip Nero (V1)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V2(Nero).zip Nero (V2)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V1(Plain).zip Plain Files(V1)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V2(1ST_READ).zip Plain Files(V2)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V1(Source).zip Source Code (v1)] *[https://files.dcemulation.org/software/dreamcast/emulators/superfamicast/SuperFamicast_V2(Source).zip Source Code (V2)] | release date=1/30/2004| author=[[Scherzo]]<br/>| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Super Famicast is a Super Nintendo emulator ported and coded by [[Scherzo]] using GCC and the KOS Development Library. Super Famicast is considered to be one of the best Super Nintendo emulators on the [[Dreamcast]] console, comparable to [[DreamSNES]]. SFC v1 currently is the fastest SNES emulator for Dreamcast if sound emulation is deactivated in options, while SFC v2 offers the best high quality SNES sound emulation on DC. It's suggested that you put both versions on one disc with [[SBInducer]] v4. '''Features:''' *Many games emulate at fullspeed with frame skipping. *Load ROMs from CD; disc swapping and .ZIP format supported *Sound *Save SRAM to VMU *Adjustable screen *Theme system including background music *Save emulator settings to VMU '''Links:''' '''Official Website:''' http://www.superfamicast.com/ [[category: emulator]] 8a3874e35ead386c864024d5a35aebf23d14d82d DreamSNES 0 830 2673 2263 2023-03-03T20:24:29Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSNES| image=[[File:Dreamsnesmainmenu.jpg|center|250px]]| homepage=[http://mc.pp.se/dc/dreamsnes/ Homepage]| version=0.9.8| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files]<br/>| release date=10/31/2002| author=[[Marcus Comstedt]]<br/>[[Peter Bortas]]<br/>[[Per Hedbor]]<br/>| original=Snes9x<br/>(Snes9x Team)| systems=Super Nintendo| best=No, try<br/>[[SNES4All|Snes4All]]| refreshrate=50Hz/60Hz| isactive=No }} ==History== DreamSNES is a port of the Snes9x [[Super NES]] emulator for Dreamcast, developed by [[Marcus Comstedt]], [[Peter Bortas]], and [[Per Hedbor]]. It is not completely fullspeed, but it can run near-fullspeed with some tweaking. It features capabilities to save games to the VMU, an optional TV-mode for creating a TV-like feel when being played on a VGA monitor, four controller support, mouse, keyboard, and lightgun support, hidden games, ROMs list support, great artwork by Kathy Choi, and groovy music by Jan Warnstam. It was translated to a high number of languages, including Finnish, French, German, Italian, Japanese, Polish, Portuguese, Romanian, Spanish, and Swedish. It was the best Snes emulator on the Dreamcast scene for many years, leaving behind a secure legacy. =Downloads= *0.9.8 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.8.zip Plain Files] *0.9.8 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.8-cdi.zip DiscJuggler] *0.9.8 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.8-nero.zip Nero] *0.9.7 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.7.zip Plain Files] *0.9.6 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.6.zip Plain Files] *0.9.5 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.5.zip Plain Files] *0.9.4 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.4.zip Plain Files] *0.9.3 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.3.zip Plain Files] *0.9.2 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.2.zip Plain Files] *0.9 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnes-0.9.zip Plain Files] =Related tools= *[https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dsinstaller.zip DreamSNES Installer] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/dreamsnesinstall.pike DreamSNES Install (Pike file)] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/Provlist.zip Provlist] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamsnes/romlst-1.2.zip RomList] =Links= * [http://www.lysator.liu.se/dreamsnes/tutorial/ Burning tutorial written by the DreamSNES team]<br /> * [http://peter.bortas.org/dreamsnes/faq.html Official DreamSNES FAQ]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21208 Bug/compatability list]<br /> * [http://dcemulation.org/phpBB/viewtopic.php?f=30&t=21518 nakamichi's bug/compatibility list] =Interview with DreamSNES team= This is an interview with [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]], the creators of [[DreamSNES]]. It was taken by Wraggster in 2001. '''DCEmulation.com: Hi, Can you please Introduce yourself?''' Peter: Hi, I'm Peter Bortas. I work together with Marcus and Per on an Internet Software company called Roxen. Marcus: Hi, I'm [[Marcus Comstedt]]. I work together with Peter and Per on an Internet Software company called Roxen (is this getting silly now?) Per: Hi, I'm [[Per Hedbor]]. I work together with Peter and Marcus on an Internet Software company called Roxen (is this getting silly now?) '''DCEmulation.com: What is your background experience with emulators, which ones do u use?''' Peter: As all ComputerSience students I've written a few emulators in and out of class. None other than DreamSNES that are released though. I rarely use emulators but when I do it's either Snes9X to play some old cRPG, or VICE to check out old and new Demos for the C64. Marcus: Well, I've also written a few emulators in my day. For the Amiga I wrote a TI-99/4A emulator and an ABC80 (Swedish computer) emulator. I've been involved in writing an Amiga emulator that runs on Sun SPARC. The most bizarre emulator I've made was a C64 emulator implemented entirely in LISP(!). The only emulator I've released previously though is the multiplatform Visual Memory emulator (SoftVMS). As for using emulators, I sometimes use the Fusion Macintosh emulator on my Amiga, and I use VGB for doing GameBoy development. Per: Well, I have written an 6808 emulator (purely CPU emulation, way back, in '91 or so), and started a few others, but nothing really useful. I only use emulators to play some FFII now and then. '''DCEmulation.com: When did you start to get involved with DreamSnes, How exactly are you involved with this wonderful emulator For the DC?''' Peter: Let's see, according to CVS I made my first changes to the Snes9X source on June 30th. As for involvement, I poke around in all parts of the code except the mpeg player. Marcus: Well, I tend to work on the low level hardware support stuff, like controllers and memory cards and what have you. I'm also doing the assembler optimized CPU assembly core (whenever I get finished with that...) Per: I got involved at July the 28th 2000, according to CVS. I optimized the options to gcc, and messed around some with the code to get the binary size down. After that, I have been working on most part of the code, but mostly the menu system and the mpeg player. '''DCEmulation.com: Have you helped any other emu authors that are porting to the Dc. I know of one person that is working on a genesis emu for the DC. Maybe you can assist him?''' Peter: People ask me questions about making emulators (and other programs) now and then, and I usually answer them if they are well thought out. I'm not involved directly in any other emulator though. Marcus: I've been helping Chuck Mason a little with his [[Gleam!]], when he asked for it. Other than that, I can't say I've had much questions from people actually working on an emulator. Per: Not really, except for answering the odd question on the DCDev mlist. DCEmulation.com: Where did you meet Marcus Comstedt, Per Hedbor & Kathy Choi? (Please Tell Kathy that I love her art its the best) Peter: Per, Marcus and I met at the Lysator Academic Computer Society ([www.lysator.liu.se www.lysator.liu.se]). We were all taking classes at the same University. Kathy has a display of her pictures at a web gallery called Elfwood ([elfwood.lysator.liu.se elfwood.lysator.liu.se]) that I help administer, and when we asked to use one of her pictures as a background for DreamSNES she agreed and even made us the DreamSNES logo. I've said it before, but I really love Kathy for letting us use her pictures. '''DCEmulation.com: Why did you choose Snes9x to be the Super Nintendo emu you port to the DC?''' Peter: Well, it wasn't even an issue of choosing between emulators. Marcus was at that time giving out all sorts of information to the public about how the Dreamcast works internally as he found it out and documented it himself. I thought it would be fun to do something other than pure tests like printing some text to the screen. It should be something that gave quick results, was fun to play with and used as many parts of what Marcus had digged out about the Dreamcast as possible. Snes9X came to my mind because *1. You can play Final Fantasy on it. That's loads of fun. *2. You don't have to do any nice looking graphics, it's already in the game. Makes for quicker results. (We hadn't recruited Cathy yet.) *3. It has potential to use controllers, mice, light guns, display, 3D-hardware, Puru-Puru packs and lots more. *4. I had looked at Snes9X source before and know it to be well written and easily understood. '''DCEmulation.com: What is the Future of DreamSnes, what might be added to improve it?''' Peter: I will have my Puru-Puru support. The original SNES didn't have one you say? Bah, one shouldn't be stopped by such trivialities. Marcus: What really needs improvement is the burning procedure. My aim is to have an automated tool (platform independant of course) to handle the procedure. '''DCEmulation.com: What do you do in your spare time when your not online?''' Peter: Sleep, socialize with friends, read books. Marcus: Spare time? Not online? What do you mean? Per: Sleep and read books, mostly. '''DCEmulation.com: Do you think you will try to Port over any other emus to the DC for Ex: Mame, System32, Turbo graphic16, Callus or UltraHLE etc.?''' Peter: Maybe, I've been playing with another emulator, but it's all vapor right now. Marcus: I'll probably take a shot at porting over my old TI-99/4A emulator when DreamSNES 1.0 is finished. '''DCEmulation.com: Do you or anyone you know have any plans to port anything to the PS2?''' Peter: Yes, I have some vague plans, but I haven't been playing with my PS2 for a while. '''DCEmulation.com: Do you think that the Dreamcast is the best console to port Emulators to because it's Windows CE compatible and will it be dificult to port to the PS2?''' Peter: It's the best console to port emulators to at the moment because *a) the amount of publicly available information about how to code for it is only rivaled by the GameBoy, and *b) it's the first console to be fast enough to emulate the SNES generation of game machines. [[WindowsCE]] has very little to do with it. It wouldn't be that hard to port to the PS2 for someone who knows how the basic hardware works. Per: [[WindowsCE]] has nothing to do with how easy it is to port emulators to it, really, since it's not possible to release emulators using it. On the other hand, the hardware in the DC is really easy to code for, that's more important than the existence or non-existence of devkits that cannot be used. '''DCEmulation.com: If there was anything you wanted to say to the people that use your Emulator or fans of the Dreamcast what would that be?''' Peter: Save cities from certain annihilation! Find the hidden game in the DreamSNES X-mas release! [[Category:Emulator]] 9987bd5a3d60843fc95d5b4564f3d3d7c44d6667 Ngine SNES9x 0 834 2674 1982 2023-03-03T20:28:08Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Ngine SNES9x| image=[[Image:Ngine-snes9x4.jpg]]| homepage=[http://www.ngine.de/ Homepage]| version=V0.40| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/ngine-snes9x-0-40.zip DiscJuggler] *[hhttps://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/ngine-snes9x-0.40n.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/ngine-snes9x-0-40-binary-only.zip Binary Only] | release date=04/25/04| author=Tubooboo| original=Snes9x / Ngine Format| systems=SNES| best=Yes.| isactive=No }} Developer: [http://www.ngine.de/ Tubooboo] Version: 0.40 Last Updated: 03-22-01 A multiplatform operating system that is easy to port games to a different operating system and platforms. This specifically is a Snes9x Port using this Ngine format. [[Image:Ngine-snes9x1.jpg]] [[Image:Ngine-snes9x3.jpg]] Status: 50% to 80% speed depending on the game. No sound. =Hisorical Files= *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/nginesnes9xdj3.zip DiscJuggler] Old version .30a *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/nginesnes9xnero.zip Nero] Old version .30a [[Category:Emulator]] a00129dce604a608d23156667b19dc3dac6ff700 2675 2674 2023-03-03T20:28:16Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Ngine SNES9x| image=[[Image:Ngine-snes9x4.jpg]]| homepage=[http://www.ngine.de/ Homepage]| version=V0.40| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/ngine-snes9x-0-40.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/ngine-snes9x-0.40n.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/ngine-snes9x-0-40-binary-only.zip Binary Only] | release date=04/25/04| author=Tubooboo| original=Snes9x / Ngine Format| systems=SNES| best=Yes.| isactive=No }} Developer: [http://www.ngine.de/ Tubooboo] Version: 0.40 Last Updated: 03-22-01 A multiplatform operating system that is easy to port games to a different operating system and platforms. This specifically is a Snes9x Port using this Ngine format. [[Image:Ngine-snes9x1.jpg]] [[Image:Ngine-snes9x3.jpg]] Status: 50% to 80% speed depending on the game. No sound. =Hisorical Files= *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/nginesnes9xdj3.zip DiscJuggler] Old version .30a *[https://files.dcemulation.org/software/dreamcast/emulators/nginesnes9x/nginesnes9xnero.zip Nero] Old version .30a [[Category:Emulator]] a26620fe4bbde6c5fb607fa6c31af3146ec1e712 Genesis Plus DC 0 839 2676 1989 2023-03-03T20:40:04Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Genesis Plus / DC| version=07/26/2006| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/Gpdc-gpwt-26072006-BA.zip GPDC BlackAura] 07/26/06 *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/gpdcq-012007.zip GPDC Quzar] 01/28/07 *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/genplus_dc_01_bin.zip GPDC v01] | release date=07/26/06| author=[[BlackAura]]| original=[http://cgfm2.emuviews.com/ GenesisPlus] by<br/>Charles MacDonald| systems=Sega Genesis| best=Yes.| isactive=Yes. }} Genesis Plus/DC is a port of Charles MacDonald's Sega Genesis/MegaDrive emulator, Genesis Plus, to the Dreamcast. It is currently the best available Sega Genesis emulator for the Dreamcast platform.It runs full speed on most games without frameskip with sound disabled. ==Features== * Full speed with full sound (no skipping!) * SRAM Saving to VMU * Great compatibility * 2 player support * 6 button pad support * Region settings (JP/US/EU) * .GEN, .BIN, .SMD, and .ZIP support * 2 CPU cores, FAME and C68K * Hardware and software rendering * Fixed graphic bugs from PVR3 version * Mono/Stereo settings (via Dreamcast BIOS) * Nice and easy to use GUI * GPDC is [[GPL|free software]] ===Missing Features=== * 4 player support * Frameskip options for the software renderer * Enhanced sound options ==History== GPDC started as a port of Genesis Plus by Charles Mac Donald. It's been in development since 2003 and a lot of progress has been made since then: BlackAura rewrote the video renderer for the Dreamcast's PowerVR2. Stef D of [http://gens.consolemul.com/ wGens] fame joined the project in 2004 to contribute fast and accurate CPU emulators: C68K & CZ80. Now with Fox68K's new SH4 Z80 emulator FAZE, and FAME, a 68K emulator written in Dreamcast's SH4 assembly language, and BlackAura working on sound emulation, the project has reached its final stage. An official release is expected for the end of this year. ===GPWT=== Until then there's the preview version of GenesisPlusDC Warmtoe & BlackAura released in 07/2006. It is called "GPWT" because it's been the first version to introduce a new GUI written by Warmtoe. ==Controls== ===Button Layout=== *Mega Drive A-Button: (X) *Mega Drive B-Button: (A) *Mega Drive C-Button: (B) *Mega Drive X-Button: (L) *Mega Drive Y-Button: (Y) *Mega Drive Z-Button: (R) *Mega Drive Start-Button: (Start) To exit a running game press (L) + (R) + (Start). ===In the Menu=== (Start) loads a game. Pressing + holding (Up)/(Down) scrolls through your game list. You can skip pages with (Left)/(Right) on the d-pad. To disable/enable 6 button support, press (X). To change the region settings, press (L). ===CPU Settings=== Some details about the different settings: Pressing (B) at the menu changes the CPU emulator. You can select either '''FAME''' - [http://www.m68k.com/fame/ Fox68k]'s great SH4 M68K emulator for fastest emulation, or '''C68K''' - [http://gens.consolemul.com/ Stef D]'s fast and accurate M68K emulator for better compatibility. ===Video Settings=== Press (A) to toggle the graphics renderer. You can select either '''HW''' - Hardware renderer written by BlackAura, using the Dreamcast's PowerVR II DC, very fast but inaccurate in a few games, or '''SW''' - Standard software renderer of GenesisPlusDC by Charles MacDonald, 100% accurate but much slower. ===Recommend Settings=== Recommend settings would be 'Render: HW' with 'CPU: FAME' - if this doesn't work for your game, try 'Render: HW' with 'CPU: C68K' (which is the default setting). ==ROMS.TXT== ===Method 1: Manual creation=== Make sure to rename the actual '.gen', '.bin', or '.zip' roms to not have spaces. ''Examples that'll work:'' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''Comix_Zone_(U)_[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone(U)[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone.bin'''' '''''The rest is straight from the readme:''''' In GPWT there is no directory browsing - just that fixed list of names for that fixed list of games. You put your (zipped) ROMS in the directory: \gpwt\data\ROMS It also expects to find a file: \gpwt\data\ROMS.txt In ROMS.TXT you can put the names of your games in there plus the name you'd like to see displayed on screen: SHINOBI.ZIP The Revenge of Shinobi 'SHINOBI.ZIP' (or 'shinobi.zip') would be your actual ROM, 'The Revenge of Shinobi' will be displayed on screen. Each file + name goes into a seperate line in ROMS.TXT. ===Method 2: Provlist by burnerO=== First download this: *Tool Set - [http://www.dcevolution.net/dsdevelopment/large/CE/gpwt-tools.zip Zipfile] Included are Provlist & Renamer which both are needed. 1. Copy your ROMs (*.zip) in /gpwt/data/ROMS/ and run Provlst.exe 2. Open ROMS.LST in Wordpad and replace ".SMC:" with ".ZIP " (space). 3. Save as 'ROMS.TXT' in /gpwt/data/ 4. Right-click on your /gpwt/data/ROMS/ folder and start Renamer 5. Click on 'Edit' -> 'Multi-Change' and replace "%a.SMC" with "%a.ZIP" 6. Click on 'A->B' to apply the changes and then close Renamer ===Method 3: Romlister by Smurph=== Download this application first: *Romlister - [http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Zipfile] 1. Zip all your roms. Keep them in a separate folder apart from the Plainfiles, or SBI, directories. 2. Start the rom lister. 3. Select the ''''data'''' subfolder from the the extracted Plainfiles, or SBI, packages. 4. Select your folder containing your zipped roms, and click on the 'Process' button. ==How To Burn== A little tutorial: ===Using Selfboot Inducer=== *1. At first you need to download [http://sbibuilder.dc-france.com/download/?idsys=2&idcat=15&idfile=115 Selfboot Inducer v4] and install it into C:/SBInducr/. *2. Then download a SBI for one of the GenesisPlusDC versions [http://www.dchelp.net/sbi HERE]. *3. Put this file into your C:/SBInducr/SBI/ folder. *4. Start C:/SBInducr/SBInducer.exe and check the SBI file showing up on the right window. Then select either "Single Menu" or "SBI2Boot" and click on 'Extract SBI'. *5. Browse to the C:/SBInducr/Inducer/gpwt/tools/ directory to find some tools. *6. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *7. Click on the 'CDRecord' button to burn the CD directly, or on the 'DiscJuggler' button to create a '.cdi' image. ===Using BootDreams=== *1. Download Bootdreams from http://dchelp.dcemulation.org, and install it. *2. Extract the plainfiles to their own folder. *3. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *4. Start Bootdreams. *5. Select the folder containing the plainfiles ''''''1st_read.bin''''''. *6. Choose your image type: '''''CDI''''', '''''NRG''''', or '''''MDF/MDS'''''. *7. Click on the process button. *8. Burn the image with your application of choice. To burn straight off Bootdreams, without creating an image, select the "CdRecord" option. To use the Bootdream's image burner select the "ImgRecord" option. ==Downloads== *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Smurph's GPWT RomLister v1.2] * Selfboot Inducer Versions: ''(To put both on one disc)'' **[http://dchelp.net/cgi-bin/sbi/browse/browse.cgi?browse&Emus Browse DCHelp's SBI File Repository] The files are called 'GenesisPlusDC-gpwt-260706-BlackAura.sbi', and 'GenesisPlusDC-gpwt-280107-Quzar.sbi'. ==Compatibility== Lists can be found here ''(W.I.P.)'': *[[GenesisPlusDC_BlackAura_list|GenesisPlusDC (BlackAura)]] fa32e82ea6f1066316a8fdb54d14a3499b49c35e DCGenerator 0 841 2677 1991 2023-03-03T20:57:41Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCGenerator| homepage=[http://dcgen.sourceforge.net/ Homepage]| version=0.35| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/dcgen.zip Plain Files]<br/>[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/dcgens.zip Sourcecode]| release date=05/24/03| author=[[ATani]] & [[MetaFox]]| original=[http://www.squish.net/generator/ Generator]<br/>by James Ponder| systems=Sega Genesis| NTSCVGAPAL=NTSC/VGA/PAL| best=No. We recommend<br/>[[Genesis Plus DC]]| isactive=No }} DCGenerator was the first Sega Genesis emulator ported to the Sega Dreamcast. It was meant as a [[GPL|free]] alternative to the Sega Genesis emulator used in [[Sega Smash Pack Volume 1]]. DCGenerator has been discontinued in 2002. Today, [[Genesis Plus DC]] is the best Sega Genesis emulator available. =Known bugs= * Some games still cause crashes * Sound is totally disabled * Video is still too slow * Slow/Complex (non-Simple) render mode has problems on some games. =Controls= '''Game Selection Key mappings'''<br/> *A - Selects Game *B - Backup/abort *L - Up 15 entries *R - Down 15 entries *Y - Rescan CD '''Options Screen Key Mappings'''<br/> *A - Enable/Disable Yes/No options *A - Increase auto Frameskip Count *B - Decrease auto Frameskip Count *START - Exit Options Screen '''Sega Genesis Controller'''<br/> *X - A *A - B *B - C '''Special Keys'''<br/> *L - Mode Change *R - Reset *L&R - Exit to Menu =Older Versions= *[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/dcgen122502.zip Unknown Version] - 12/25/02 *[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/DCGen_034b_Nero.zip 0.34b Nero Image] - 04/11/02 *[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/DCGen_034b_DJ.zip 0.34b DiscJuggler Image] - 04/11/02 *[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/dcgen-bin-0.34b.zip 0.34b Plain Files] - 04/09/02 *[https://files.dcemulation.org/software/dreamcast/emulators/dcgenerator/dcgen-0.34.zip Plain Files] - 11/02/01 a3ee329705578086b7590ced59e8fdb17588950d Ljsdcgen 0 842 2678 1992 2023-03-03T21:01:39Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=ljsdcgen| homepage=[http://www.ljsdcdev.net Homepage]| version=1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/ljsdcgen/ljsdcgen-v1-bin.tar.bz2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/ljsdcgen/ljsdcgen-v1-src.tar.bz2 Source Code] | release date=5/17/03| author=Lawrence Sebald<br/>(BlueCrab)| original=[http://www.squish.net/generator/ Generator]<br/>by James Ponder| systems=Sega Genesis| best=No| refreshrate=60Hz| isactive=No }} ljsdcgen is a port of James Ponder's Generator to the Dreamcast using SDL. This emulator was discontinued shortly after its first release. =Known bugs= *It is very very slow. 64428ea3377ed5299d6be83824ab17c42d2ae851 SMS Plus DC 0 844 2679 1995 2023-03-03T21:10:54Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS Plus DC| image=[[File:smsplus.png|center|250px]]| homepage=[http://www.pascalorama.info/article.php?news=19&cat=8 Homepage]| version=0.2b| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/smsplusdc/smsplusdcv02b.zip Plain Files]<br />[https://files.dcemulation.org/software/dreamcast/emulators/smsplusdc/smsplusdc-2.0B.tar.gz Source Code]| release date=February 20, 2005| author=[[Pascal Bosquet]]<br />Help by [[Heliophobe]]| original=[http://cgfm2.emuviews.com/smsplus.php SMS Plus]| systems=Master System, GameGear| best=Yes| refreshrate=50Hz/60Hz| isactive=No }} SMS Plus DC is the best MasterSystem/Gamegear emulator for the Dreamcast console. It was mostly developed by [[Pascal Bosquet]]. It runs fullspeed, without frameskipping and with sound enabled. ==Features== *No frameskip with sound *Hi-res display (640*480) *Intuitive GUI *Two players *Bilinear filtering *Speech emulation *Sram and game state saving *Screen Adjustment *Great compatibility *PAL support *Rom snapshot preview in the gui *Speed: 99% *Sound: 99% ==Links== *[http://www.pascalorama.info/article.php?news=19&cat=8 Official website] *[https://github.com/pascalorama/smsplusdc Github repo] fa0a1d518e813c780896838bfd3ea2f0f5752366 2680 2679 2023-03-03T21:13:36Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS Plus DC| image=[[File:smsplus.png|center|250px]]| homepage=[http://www.pascalorama.info/article.php?news=19&cat=8 Homepage]| version=0.2b| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/smsplusdc/smsplusdcv02b.zip Plain Files]<br />[https://files.dcemulation.org/software/dreamcast/emulators/smsplusdc/smsplusdc-2.0B.tar.gz Source Code]| release date=February 20, 2005| author=[[Pascal Bosquet]]<br />Help by [[Heliophobe]]| original=[http://cgfm2.emuviews.com/smsplus.php SMS Plus]| systems=Master System, GameGear| best=Yes| refreshrate=50Hz/60Hz| isactive=No }} SMS Plus DC is the best MasterSystem/Gamegear emulator for the Dreamcast console. It was mostly developed by [[Pascal Bosquet]]. It runs fullspeed, without frameskipping and with sound enabled. ==Features== *No frameskip with sound *Hi-res display (640*480) *Intuitive GUI *Two players *Bilinear filtering *Speech emulation *Sram and game state saving *Screen Adjustment *Great compatibility *PAL support *Rom snapshot preview in the gui *Speed: 99% *Sound: 99% ==Historical files== *[https://files.dcemulation.org/software/dreamcast/emulators/smsplusdc/smsplusdcv01.zip Version v0.1] ==Links== *[http://www.pascalorama.info/article.php?news=19&cat=8 Official website] *[https://github.com/pascalorama/smsplusdc Github repo] 05d164ecf97925e577e15a51c08a185b988bd233 SMEG 0 846 2681 1997 2023-03-03T21:21:51Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMEG| homepage=[http://www.smspower.org/heliophobe/ Homepage]| version=0.84| image=[[File:SMEG 04.jpg|center|250px]]| downloads=Local links: [https://files.dcemulation.org/software/dreamcast/emulators/smeg/smeg_084_plain.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smeg_084_nero.zip Nero Image] *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smeg_084_dj.zip DiscJuggler image] | release date=10/14/01| author=[[Heliophobe]]| original=Nothing| systems=Master System<br/>GameGear| best=No, we recommend<br/>[[SMS Plus DC]]| isactive=No| refreshrate=50Hz \ 60Hz }} Smeg is an emulator the Sega Master System (SMS) and Game Gear (GG) game consoles, which runs on the Sega Dreamcast console. It features full speed, excellent sound but it lacks any sort of save support. Two players are supported. ==Known Bugs== * No Save Support * Some Games are Incompatible * Rom Loader Flaky when no disc is inserted, or no roms are found on disc * 50hz gameplay makes speech playback choppy * Out Run 3D won't detect paddle controller (even though supported) ==Controls== Dreamcast \ SMS or GG * D-Pad \ D-Pad * A and B \ 1 and 2 (reversible) * Start \ Pause (SMS), Start (GG) * X + Start to do soft reset * Y Returns to SMEG menu * Analog stick \ Controls Paddle (SMS) ==Historical files== *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smegpreview-noserial.zip SMEGPreviewNoSerial] b7d69f60aeef9dac0890fcfedaba3f3d328e0d30 2682 2681 2023-03-03T21:22:02Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMEG| homepage=[http://www.smspower.org/heliophobe/ Homepage]| version=0.84| image=[[File:SMEG 04.jpg|center|250px]]| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smeg_084_plain.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smeg_084_nero.zip Nero Image] *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smeg_084_dj.zip DiscJuggler image] | release date=10/14/01| author=[[Heliophobe]]| original=Nothing| systems=Master System<br/>GameGear| best=No, we recommend<br/>[[SMS Plus DC]]| isactive=No| refreshrate=50Hz \ 60Hz }} Smeg is an emulator the Sega Master System (SMS) and Game Gear (GG) game consoles, which runs on the Sega Dreamcast console. It features full speed, excellent sound but it lacks any sort of save support. Two players are supported. ==Known Bugs== * No Save Support * Some Games are Incompatible * Rom Loader Flaky when no disc is inserted, or no roms are found on disc * 50hz gameplay makes speech playback choppy * Out Run 3D won't detect paddle controller (even though supported) ==Controls== Dreamcast \ SMS or GG * D-Pad \ D-Pad * A and B \ 1 and 2 (reversible) * Start \ Pause (SMS), Start (GG) * X + Start to do soft reset * Y Returns to SMEG menu * Analog stick \ Controls Paddle (SMS) ==Historical files== *[https://files.dcemulation.org/software/dreamcast/emulators/smeg/smegpreview-noserial.zip SMEGPreviewNoSerial] c2616531a6e31b12604fe89cf2943c7712b9e636 SMS Plus 0 847 2683 1998 2023-03-03T21:23:33Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS Plus| image=No screenshot available| homepage=[http://devcast.wolfnet.org/ Homepage]| version=Beta 7| downloads= [https://files.dcemulation.org/software/dreamcast/emulators/smsplus/smsplus7.zip Plain Files]<br/>| release date=Unknown| author=ss_teven| original=Charles Mac Donald| systems=Sega Master System Game Gear| best=No.| isactive=No }} Developer: [http://devcast.wolfnet.org/ ss_teven - DevCast] Version: Beta 7 Last Updated: 07-14-01 This is a very simple port of SMS Plus by Charles Mac Donald to the Dreamcast. =Old Versions= [https://files.dcemulation.org/software/dreamcast/emulators/smsplus/smsplus62.zip Plain Files Version] Beta 6.1 [[Category:Emulator]] 23558d24f254f2c184e4a4857fbea20637f770aa DreamSMS 0 851 2684 2002 2023-03-03T21:26:35Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSMS| image=See below| homepage=Unknown| version=.01| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreamsms/dreamsms01.zip Plain Files] - 03/06/01<br/>| release date=Unknown| author=Jos Kwanten| original=N/A| systems=Sega Master System / Game Gear| best=Unknown| isactive=Unknown }} Developer: Jos Kwanten Version: .01 Last Updated: 03-06-01 A Sega Master System emulator for the Dreamcast which runs Game Gear games as well. Made by the same guy who brought us the MSX emulator. Only runs Game Gear games at this point. Status: Running full speed with sound. ==Screen Shots== <gallery> Image:sms-001s.jpg Image:sms-004s.jpg Image:sms-005s.jpg </gallery> 40fb3028e9711d919145503019c8a42d13f6998f SMS+SDL\DC 0 852 2685 2003 2023-03-03T21:29:09Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=SMS+SDL\DC| homepage=[http://dchelp.dcemulation.org/ Homepage]| version=0.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/smssdldc/smssdldc_01.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/smssdldc/smssdldc_01_src.zip Sourcecode] | release date=4/01/08| author=[[fackue]]| original=[http://cyxdown.free.fr/ SMS+SDL]<br/>by Gregory Montoir| systems=GameGear<br/>Master System| refreshrate=60Hz| best=No. We recommend<br/>[[SMS Plus DC]]| isactive=No }} SMS+SDL was a port done by [[fackue]] as an attempt to get more familiar with Dreamcast programming. Though the port works and runs at full speed with sound, he's said that it's unlikely he will continue development. You can discuss about SMS+SDL\DC in [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=96944 the official release thread in our forums]. ==Known Bugs== * No way to get back to menu after loading game 8f724a3e26bba05c5212d7dca03e9b73ca520ee1 Dreamcast emulators 0 4 2686 2341 2023-03-03T21:31:51Z Unknown user 0 /* DreamEmu */ wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Other older emulators== These emulators are listed mostly for historical/archival reasons. ===Chankast=== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ===Makaron=== *Makaron [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] ===DreamEmu=== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-003.zip v0.03 - 08/03/01], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-002.zip v0.02], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ===Dreamer=== *Developed by ElSemi in late 2000 into mid-2001, Dreamer was the first working and released Dreamcast emulator for PC. *Latest version: Alpha 0.25 - Download [http://www.dcemulation.org/files/pcemu/dreamer002.zip v0.02] *[Dreamer](http://emulatronia.com/dcemu.htm) *SH4: All opcodes is emulated (100% have not been proven) interprets. Those of movements of data to memory and jumps are emulated using dynamic recompilación. *FPU: All opcodes emulated for want of the 2 specific instructions of the Dreamcast. > uses the interpreter - Slow. *PowerVR: The basic part of the hardware 2d works (Framebuffer correctly and control registries). It lacks the way of video 555. We are at the moment looking for information on the hardware 3d and display lists. *JoyPad: Emulated completely. *Maple Bus: The control registries have been identified and will be working shortly. *Sound: Nothing yet. *CDROM: Almost emulated. *DEBUGGER: The emulator takes integrated to debugger (that is a little patatero but it plays his role). Executing debugger implies that the execution of the program is much more slow. The handling keys are the following ones: *F5: Go (uninterrupted Execution)<br/> *F7: Draw up Into (to execute entering the subroutines)<br/> *F8: Step Over (To execute without entering the subroutines, does not work to 100%) *Commandos: The commandos are written in the inferior part of the window of the code:<br/> **G (Just as F5)<br/> **G direction (Executes until that direcci¢n. in hex)<br/> **D direction (shows the memory of the specified direction. in hex)<br/> **D registry (it shows the memory of the direction loaded in the chosen registry)<br/> **And direction data (writes in the direction the specified data. 0-FF in hex)<br/> **R registry value (loads the value in the registry. 0-FFFFFFFF in hex)<br/> **S (it stops the single emulation works in Go way)<br/> **F (it draws framebuffer)<br/> **X (to leave)<br/> **Z (reset, cracks, not to use)<br/> **WD 0|1 (oculta|muestra window of data)<br/> **WR 0|1 (oculta|muestra window of registries)<br/> **WM 0|1 (oculta|muestra window of messages)<br/> **WC 0|1 (oculta|muestra code window, nor is happened to you, but where you write) ===Swirly=== *[Swirly](http://swirly.sourceforge.net/) b9336ddfcb09bc41e8b57999afb3c8a7e63b47b2 2687 2686 2023-03-03T21:34:54Z Unknown user 0 /* Dreamer */ wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Other older emulators== These emulators are listed mostly for historical/archival reasons. ===Chankast=== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ===Makaron=== *Makaron [[File:Swirly.jpg|thumb|Swirly running Dan Potter's Stars demo]] ===DreamEmu=== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-003.zip v0.03 - 08/03/01], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-002.zip v0.02], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ===Dreamer=== *Developed by ElSemi in late 2000 into mid-2001, Dreamer was the first working and released Dreamcast emulator for PC. *Latest version: Alpha 0.25 - Download [https://files.dcemulation.org/software/dcemulators/dreamer/dreamer002.zip v0.02] *[Dreamer](http://emulatronia.com/dcemu.htm) *SH4: All opcodes is emulated (100% have not been proven) interprets. Those of movements of data to memory and jumps are emulated using dynamic recompilación. *FPU: All opcodes emulated for want of the 2 specific instructions of the Dreamcast. > uses the interpreter - Slow. *PowerVR: The basic part of the hardware 2d works (Framebuffer correctly and control registries). It lacks the way of video 555. We are at the moment looking for information on the hardware 3d and display lists. *JoyPad: Emulated completely. *Maple Bus: The control registries have been identified and will be working shortly. *Sound: Nothing yet. *CDROM: Almost emulated. *DEBUGGER: The emulator takes integrated to debugger (that is a little patatero but it plays his role). Executing debugger implies that the execution of the program is much more slow. The handling keys are the following ones: *F5: Go (uninterrupted Execution)<br/> *F7: Draw up Into (to execute entering the subroutines)<br/> *F8: Step Over (To execute without entering the subroutines, does not work to 100%) *Commandos: The commandos are written in the inferior part of the window of the code:<br/> **G (Just as F5)<br/> **G direction (Executes until that direcci¢n. in hex)<br/> **D direction (shows the memory of the specified direction. in hex)<br/> **D registry (it shows the memory of the direction loaded in the chosen registry)<br/> **And direction data (writes in the direction the specified data. 0-FF in hex)<br/> **R registry value (loads the value in the registry. 0-FFFFFFFF in hex)<br/> **S (it stops the single emulation works in Go way)<br/> **F (it draws framebuffer)<br/> **X (to leave)<br/> **Z (reset, cracks, not to use)<br/> **WD 0|1 (oculta|muestra window of data)<br/> **WR 0|1 (oculta|muestra window of registries)<br/> **WM 0|1 (oculta|muestra window of messages)<br/> **WC 0|1 (oculta|muestra code window, nor is happened to you, but where you write) ===Swirly=== *[Swirly](http://swirly.sourceforge.net/) 38926c29c0d4dc1843d3d2595e69be7d78b098fc Yabause 0 858 2688 2010 2023-03-03T21:38:10Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Yabause| image=[[File:Yabause-20061218-5.png|center|250px]]| homepage=[http://yabause.org Homepage]| version=0.9.11| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/yabause/yabause-0.9.11-dc.tar.bz2 Plain Files]<br/>[https://files.dcemulation.org/software/dreamcast/emulators/yabause/yabause-0.9.11.tar.gz Source Code]| release date=11/28/11| author=Lawrence Sebald<br/>([[BlueCrab]])| original=[http://yabause.org Yabause]<br/>by the Yabause team| systems=Sega Saturn| best=Yes| refreshrate=60Hz| isactive=Yes }} Yabause is a multi-platform, open-source Sega Saturn emulator. The Dreamcast port is maintained by [[BlueCrab]]. The Dreamcast port tops out at 10FPS, but will not generally reach that speed during normal game play (expect around 4FPS in games). =Known bugs= *Yabause is nowhere near full-speed on the Dreamcast and it probably won't be for a long time. *There are still many unsupported features of the Saturn hardware. =Controls= '''User Interface'''<br/> *Press START to boot the CD that is currently in the Dreamcast's GD-ROM drive. '''Buttons'''<br/> *A - A *B - B *X - X *Y - Y *L - L *R - R * Joystick Right - C * Joystick Down - Z *START - START *Directional Pad - Directional Pad c2076d8ada5a172fcae89e94c2e98b8595e82c0e Dream-O-Rama 0 856 2689 2007 2023-03-03T21:40:50Z Unknown user 0 wikitext text/x-wiki *Developer: Spoutnick Team *Version: Vol #1 *Last Updated: 05-28-01 A new Sega SG-1000/3000 emulator based on the Past-O-Rama engine. *100% speed with high quality sound *Hi-res display (640*480) and intuitive G.U.I. *Great compatibility and 2 players option ==Screenshots== <gallery> [[Image:Dorama-screen3.jpg]] [[Image:Dorama-screen2.gif]] [[Image:Dorama-screen1.gif]] </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/dreamorama/dorsg1kdij.zip Disk Juggler] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamorama/dorsg1ksc.zip Plain Files] scrambled *[https://files.dcemulation.org/software/dreamcast/emulators/dreamorama/dorsg1k.zip Plain Files] unscrambled 61a44785fe3319cb222dd99ff66cd05e758a4fbe 2690 2689 2023-03-03T21:41:09Z Unknown user 0 /* Screenshots */ wikitext text/x-wiki *Developer: Spoutnick Team *Version: Vol #1 *Last Updated: 05-28-01 A new Sega SG-1000/3000 emulator based on the Past-O-Rama engine. *100% speed with high quality sound *Hi-res display (640*480) and intuitive G.U.I. *Great compatibility and 2 players option ==Screenshots== <gallery> Image:Dorama-screen3.jpg Image:Dorama-screen2.gif Image:Dorama-screen1.gif </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/dreamorama/dorsg1kdij.zip Disk Juggler] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamorama/dorsg1ksc.zip Plain Files] scrambled *[https://files.dcemulation.org/software/dreamcast/emulators/dreamorama/dorsg1k.zip Plain Files] unscrambled 74175ee0c3e9068684940319b1f0308126442526 MDCNG 0 859 2691 2011 2023-03-03T21:45:24Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=MDCNG| image=''No Image Available| homepage=[http://dev.dcemulation.org/mamed/neomaim.html Homepage]| version=v2.82| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/mdcng/MDCNGv2.82.zip Plain files]| release date=05/07/2003| author=[[Warmtoe]]| original=[MAME]| systems=Neo-Geo| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=''Unknown| best=No,<br/>[[AES4All]]| isactive=No| }} ==History== A NeoGeo emulator for the Dreamcast. MDCNG ''(a.k.a. NeoGeo Maim)'' has a nice GUI and tons of options! It's very like [[Maim]] - but quicker. Sound makes everything slower - but it does work... ==Downloads== * v2.82 - [https://files.dcemulation.org/software/dreamcast/emulators/mdcng/MDCNGv2.82.zip Plainfiles] - 05/07/2003 * v2.82 - [https://files.dcemulation.org/software/dreamcast/emulators/mdcng/Mdcng-2.82.sbi SBI] - 05/07/2003 * v2.7 - [https://files.dcemulation.org/software/dreamcast/emulators/mdcng/MDCNGv2.7.zip Plainfiles] - ''Unknown release date * ??? - [https://files.dcemulation.org/software/dreamcast/emulators/mdcng/MDCNGv2.sbi SBI File] 544838b63ec06be270373e86cc385e24eae0a77c AES4All 0 864 2692 2016 2023-03-03T21:51:53Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=AES4ALL| image=[[Image:neo4all.png|center|280px| Metal Slug 2]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 2| downloads=[http://chui.dcemu.co.uk/releases/aes4all-beta2-fix.rar Plainfiles]| release date=04/04/2007| author=[[Chui]]<br/>| original=[[NeoCD/SDL_DC|NeoCD DC]]/<br/>[http://gngeo.berlios.de/ GnGeo]/<br/>[http://pacifi3d.retrogames.com/neocdsdl/index.html NeoCD/SDL]| systems=NeoGeo AES/MVS| best=Yes.| refreshrate=50Hz / 60Hz| isactive=Unknown }} ==History== AES4ALL ''(a.k.a. Neo4all/AES)'' is a fork of Neo4all by [[Chui]], and emulates the NeoGeo AES/MVS video game system. The current release offers amazing compatibility and full speed emulation with full BGM and SFX. Beta 2 introduces a brandnew GUI with customizable controls, a rewrite of the Yamaha 2610 FM emulator, the latest FAME and FAZE versions, much faster ROM loading and an additional MMU cache level which enables to use the Dreamcast's 2MByte SRAM. To use the maximum amount of the Dreamcast's RAM, it even allows standalone single game discs which avoid loading the menu and boot straight to the game. [[Image:Puzzbob.gif| Puzzle Bobble]] ===Features=== * Emulates Neo Geo MVS & AES games * 100% full speed without frameskip on most games * 2 Player support * Great compatibility * MMU technique for playing games larger than the DC's RAM * Second MMU cache level using the Dreamcast's SRAM (+2MByte) * Full VMU Support * Region Selection * Nice GUI with Music * Arcade Stick Support * Customizable Controls * Safe Reset Function * Standalone CD Feature (the emu + your game on 1 CD) * Low level CD-ROM access for fast CD swap. * Super fast ROM loading * Main CPU Motorola 68000: * FAME emulation library by Fox68k * Sound CPU Zilog Z80: * FAZE Z80 emulation core by Fox68k * NeoGeo CD Video Display Processor: * Overclock & Underclock Options for both CPUs * Custom PowerVR2 based engine by Chui (sdl_gp32 -at- yahoo.es) * Tile caching. * SQ data transfer. * Optional bilinear filtering * YM2610 FM sound emulation. * Disc Swap with your ROM disc [[Image:Aerofight.gif| Aero Fighters]] [[Image:Artfight.gif| Art of Fighting]] ===NeoGeoCD=== There's also a fork of this emulator that plays NeoGeoCD games called [[NEO4ALL]]. ==Downloads== * Aes4all Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/aes4all-beta4.rar Plain files] * Aes4all Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/aes4all-beta2-fix.rar Plain files] - 04/04/2007 * Aes4all Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/neo4all_aes-beta1.rar Plain files] - ''Unknown release date * Aes4all Alpha - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/neo4all_aes-alpha.rar Plain files] ==Burning== ===Needed BIOS Files=== The emulator needs pre-converted AES files that contain portions of the AES BIOS to work. So in order to convert your MVS ROMs for Neo4All/AES, you need to search for these files at first: * aes-bios.bin (128KByte) * ng-lo.rom (64KByte) * ng-sfix.rom (128KByte) * sfix.sfx (128KByte) Google for "Neo Geo BIOS" and once you got the different BIOS distributions that are floating around, unzip them and copy the files listed above into your /NEO4ALL_AES-ALPHA/WINDOWS/CONVERTNEO/BIOS/ folder. Once you found "NG-SFIX.ROM" (128k), simply rename it to "SFIX.SFX". Pay attention to the ROM size! There are TWO DIFFERENT versions of "NG-LO.ROM", one is 128KByte in size, the other 64KByte. The 64KByte version is needed here. InsaneDavid posted this over at DCEmulation.org: Most of the time in a NeoGeo BIOS package if "ng-lo.rom" is present it will be the 128KByte version. However if there isn't present, a 64KByte file called "000-lo.lo" usually is. "000-lo.lo" is the 64KByte version of "ng-lo.rom" - simply rename it to "ng-lo.rom" and you've got what you need. ====Uni-BIOS==== If you are not able for whatever reasons to find the proper "AES-BIOS.BIN", you could try to google for the Uni-BIOS. Rename "UNI-BIOS.ROM" to "AES-BIOS.BIN" and put it along with the other BIOS files in your /NEO4ALL_AES-ALPHA/WINDOWS/CONVERTNEO/BIOS/ folder. Then convert your games. Note that only Uni-BIOS v1.2 will work with the Dreamcast version of Neo4All/AES. Thanks to SUPNEO for the info. ===How To Build A Selfbootable Neo4ALL/AES Disc=== Building a selfbootable disc of Neo4All/AES is the same as with all Dreamcast games or emus. It can be done easily with the available selboot apps like Dir2Boot, Selfboot or SBInducer (where you'd simply have put all files in the /Inducer/ folder). Suggested is BootDreams by fackue as it's by far the best selfboot app. You can get it from here: http://www.dchelp.dcemulation.org/ Just point BootDreams to the folder that's containing Neo4All's 1ST_READ.BIN file and your games. Here's the complete needed disc structure that folder should hold: * ../Neo4AES/1st_read.bin (the emulator itself) * ../Neo4AES/mslugx.aes (your converted games) * ../Neo4AES/NEO4ALL/ (folder) An IP.BIN is not needed if you use BootDreams as it will create the file automatically for you! In general, all IP.BINs are identical so if you don't use BootDreams, just copy that file from any other game or emu. The /NEO4ALL/ folder contains a lot of files like "AES.mod", "Background0.bmp", etc. Some of these are not necessary and could as well be deleted. In fact, deleting them will also free some valuable Kbytes of the DC's RAM and thus improving the performance a lot by definitly reducing the loading times noticably (e.g. SNK vs Capcom, Metal Slug X, etc.), so it's really suggested to delete all unneccessary files. Here's a complete list of all of those files that are needed for the emu to work, so they better should not be deleted: * Background_AES.bmp * Beep.wav * Colors.txt * Loading.bmp * Memcard.bin * Patch.prg * Splash_AES.bmp * Startup.bin * Text.bmp * Text2.bmp * Window.bmp ==Links== * [http://www.dreamcast-scene.com/index.php/Main/AESRecommendGames Recommended AES Games] [[Category:Emulator]] 25dbf71a32f498e74a10cba9c7d3f2dfbad2a90f 2693 2692 2023-03-03T21:52:58Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=AES4ALL| image=[[Image:neo4all.png|center|280px| Metal Slug 2]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 4| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/aes4all/aes4all-beta4.rar Plainfiles]| release date=04/04/2007| author=[[Chui]]<br/>| original=[[NeoCD/SDL_DC|NeoCD DC]]/<br/>[http://gngeo.berlios.de/ GnGeo]/<br/>[http://pacifi3d.retrogames.com/neocdsdl/index.html NeoCD/SDL]| systems=NeoGeo AES/MVS| best=Yes.| refreshrate=50Hz / 60Hz| isactive=Unknown }} ==History== AES4ALL ''(a.k.a. Neo4all/AES)'' is a fork of Neo4all by [[Chui]], and emulates the NeoGeo AES/MVS video game system. The current release offers amazing compatibility and full speed emulation with full BGM and SFX. Beta 2 introduces a brandnew GUI with customizable controls, a rewrite of the Yamaha 2610 FM emulator, the latest FAME and FAZE versions, much faster ROM loading and an additional MMU cache level which enables to use the Dreamcast's 2MByte SRAM. To use the maximum amount of the Dreamcast's RAM, it even allows standalone single game discs which avoid loading the menu and boot straight to the game. [[Image:Puzzbob.gif| Puzzle Bobble]] ===Features=== * Emulates Neo Geo MVS & AES games * 100% full speed without frameskip on most games * 2 Player support * Great compatibility * MMU technique for playing games larger than the DC's RAM * Second MMU cache level using the Dreamcast's SRAM (+2MByte) * Full VMU Support * Region Selection * Nice GUI with Music * Arcade Stick Support * Customizable Controls * Safe Reset Function * Standalone CD Feature (the emu + your game on 1 CD) * Low level CD-ROM access for fast CD swap. * Super fast ROM loading * Main CPU Motorola 68000: * FAME emulation library by Fox68k * Sound CPU Zilog Z80: * FAZE Z80 emulation core by Fox68k * NeoGeo CD Video Display Processor: * Overclock & Underclock Options for both CPUs * Custom PowerVR2 based engine by Chui (sdl_gp32 -at- yahoo.es) * Tile caching. * SQ data transfer. * Optional bilinear filtering * YM2610 FM sound emulation. * Disc Swap with your ROM disc [[Image:Aerofight.gif| Aero Fighters]] [[Image:Artfight.gif| Art of Fighting]] ===NeoGeoCD=== There's also a fork of this emulator that plays NeoGeoCD games called [[NEO4ALL]]. ==Downloads== * Aes4all Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/aes4all-beta4.rar Plain files] * Aes4all Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/aes4all-beta2-fix.rar Plain files] - 04/04/2007 * Aes4all Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/neo4all_aes-beta1.rar Plain files] - ''Unknown release date * Aes4all Alpha - [https://files.dcemulation.org/software/dreamcast/emulators/aes4all/neo4all_aes-alpha.rar Plain files] ==Burning== ===Needed BIOS Files=== The emulator needs pre-converted AES files that contain portions of the AES BIOS to work. So in order to convert your MVS ROMs for Neo4All/AES, you need to search for these files at first: * aes-bios.bin (128KByte) * ng-lo.rom (64KByte) * ng-sfix.rom (128KByte) * sfix.sfx (128KByte) Google for "Neo Geo BIOS" and once you got the different BIOS distributions that are floating around, unzip them and copy the files listed above into your /NEO4ALL_AES-ALPHA/WINDOWS/CONVERTNEO/BIOS/ folder. Once you found "NG-SFIX.ROM" (128k), simply rename it to "SFIX.SFX". Pay attention to the ROM size! There are TWO DIFFERENT versions of "NG-LO.ROM", one is 128KByte in size, the other 64KByte. The 64KByte version is needed here. InsaneDavid posted this over at DCEmulation.org: Most of the time in a NeoGeo BIOS package if "ng-lo.rom" is present it will be the 128KByte version. However if there isn't present, a 64KByte file called "000-lo.lo" usually is. "000-lo.lo" is the 64KByte version of "ng-lo.rom" - simply rename it to "ng-lo.rom" and you've got what you need. ====Uni-BIOS==== If you are not able for whatever reasons to find the proper "AES-BIOS.BIN", you could try to google for the Uni-BIOS. Rename "UNI-BIOS.ROM" to "AES-BIOS.BIN" and put it along with the other BIOS files in your /NEO4ALL_AES-ALPHA/WINDOWS/CONVERTNEO/BIOS/ folder. Then convert your games. Note that only Uni-BIOS v1.2 will work with the Dreamcast version of Neo4All/AES. Thanks to SUPNEO for the info. ===How To Build A Selfbootable Neo4ALL/AES Disc=== Building a selfbootable disc of Neo4All/AES is the same as with all Dreamcast games or emus. It can be done easily with the available selboot apps like Dir2Boot, Selfboot or SBInducer (where you'd simply have put all files in the /Inducer/ folder). Suggested is BootDreams by fackue as it's by far the best selfboot app. You can get it from here: http://www.dchelp.dcemulation.org/ Just point BootDreams to the folder that's containing Neo4All's 1ST_READ.BIN file and your games. Here's the complete needed disc structure that folder should hold: * ../Neo4AES/1st_read.bin (the emulator itself) * ../Neo4AES/mslugx.aes (your converted games) * ../Neo4AES/NEO4ALL/ (folder) An IP.BIN is not needed if you use BootDreams as it will create the file automatically for you! In general, all IP.BINs are identical so if you don't use BootDreams, just copy that file from any other game or emu. The /NEO4ALL/ folder contains a lot of files like "AES.mod", "Background0.bmp", etc. Some of these are not necessary and could as well be deleted. In fact, deleting them will also free some valuable Kbytes of the DC's RAM and thus improving the performance a lot by definitly reducing the loading times noticably (e.g. SNK vs Capcom, Metal Slug X, etc.), so it's really suggested to delete all unneccessary files. Here's a complete list of all of those files that are needed for the emu to work, so they better should not be deleted: * Background_AES.bmp * Beep.wav * Colors.txt * Loading.bmp * Memcard.bin * Patch.prg * Splash_AES.bmp * Startup.bin * Text.bmp * Text2.bmp * Window.bmp ==Links== * [http://www.dreamcast-scene.com/index.php/Main/AESRecommendGames Recommended AES Games] [[Category:Emulator]] 1503cc36591def8b9f13a259e87ddf8e3b586dfd NeoCD/SDL DC 0 865 2694 2017 2023-03-03T21:59:13Z Unknown user 0 wikitext text/x-wiki Developer: Ian Micheal Updated: 18-05-04 A very cool port of the Neo Geo CD emulator NEOCD/SDL [http://www.dcemulation.org/phpBB/viewtopic.php?p=518878#518878 NeoGeoCD/SDL V7 Game Testing Topic] Dreamcast Port Credits: [[Ian Micheal]], [[Fosters]], Troy "[[GPF]]" Davis, [[BlackAura]], [[BlueCrab]] CREDITS -------------------------------- Fabrice Martinez - The original NeoCD emulator Fosters - SDL port Caz - For the BeOS NeoCD/SDL build Karl Stenerud - The Musashi M680x0 emulator Neil Bradley (neil@synthcom.com) - Multi-Z80 CPU emulator Tatsuyuki Satoh - YM2610 Mame core Derek Liauw Kie Fa. - 2xSaI engine Sam Lantinga (et al) - Simple DirectMedia Layer Quzar- Region selector, frameskip, frame limiting, auto loading, many bugfixes and optimizations. Mekanizer - proper vmu display *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7bin.rar v7 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7.rar v7 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6bin.rar v6 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6src.rar v6 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/sourcev5_5.rar v5.5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5bin.rar v5 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5_source.rar v5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v4.rar v4 Plain Files] 3b0ca09d63415c9fc74962d8f4776ec289ec5740 2695 2694 2023-03-03T21:59:24Z Unknown user 0 wikitext text/x-wiki Developer: Ian Micheal Updated: 18-05-04 A very cool port of the Neo Geo CD emulator NEOCD/SDL [http://dcemulation.org/phpBB/viewtopic.php?p=518878#518878 NeoGeoCD/SDL V7 Game Testing Topic] Dreamcast Port Credits: [[Ian Micheal]], [[Fosters]], Troy "[[GPF]]" Davis, [[BlackAura]], [[BlueCrab]] CREDITS -------------------------------- Fabrice Martinez - The original NeoCD emulator Fosters - SDL port Caz - For the BeOS NeoCD/SDL build Karl Stenerud - The Musashi M680x0 emulator Neil Bradley (neil@synthcom.com) - Multi-Z80 CPU emulator Tatsuyuki Satoh - YM2610 Mame core Derek Liauw Kie Fa. - 2xSaI engine Sam Lantinga (et al) - Simple DirectMedia Layer Quzar- Region selector, frameskip, frame limiting, auto loading, many bugfixes and optimizations. Mekanizer - proper vmu display *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7bin.rar v7 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7.rar v7 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6bin.rar v6 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6src.rar v6 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/sourcev5_5.rar v5.5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5bin.rar v5 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5_source.rar v5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v4.rar v4 Plain Files] f69b05cdea64f7b9b41dbd8e729432670c9a8e7e NeoDC 0 867 2696 2020 2023-03-03T22:01:18Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NeoDC |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:samsho1.gif| Samurai Shodown]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.screamcast.net/ Homepage]<br/>''(Defunct Domain)}}} |- style="background:#ffffff" |Latest Version || {{{version|v2.3}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/emulators/neodc/NeoDC_scrambled.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|10/04/05}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://pacifi3d.retrogames.com/neocdsdl/ NeoCD/SDL]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|Neo-Geo CD}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|No}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== NeoCD is the name of the original Neo Geo CD emulator by Fabrice Martinez. NeoCD/SDL was a port of Neo Geo CD to the SDL library. The Dreamcast port, originally known as NeoCD/SDL DC, was a joint effort by [[Quzar]], Fosters, [[BlueCrab]], [[GPF]], [[Ian Micheal]], and [[BlackAura]]. After version 9.1, the emulator was rewritten to use [[KallistiOS]] directly instead of SDL, and was renamed NeoDC. The overall aim of NeoDC was to be independent from SDL, be fullspeed, have full sound effects, and have full CDDA CD track streaming support. NeoDC was voted as the best emulator of 2004 by [http://www.dcemu.co.uk/ DCEmu], and is definately not something to be missed by any Dreamcast owner. ==Downloads== * NeoDC v2.3 - [https://files.dcemulation.org/software/dreamcast/emulators/neodc/NeoDC_scrambled.rar Plainfiles] ''(fixed)'' - 04/12/05 * NeoDC v2.3 - [https://files.dcemulation.org/software/dreamcast/emulators/neodc/NeoDCv2.3src.zip Source] - 04/10/05 * NeoDC v2.2 - [https://files.dcemulation.org/software/dreamcast/emulators/neodc/NeoDCv2.2.zip Plainfiles] - 02/25/05 * NeoDC v2.2 - [https://files.dcemulation.org/software/dreamcast/emulators/neodc/NeoDCv2.2src.zip Source] - 02/25/05 ==Links== * [http://www.dreamcast-scene.com/index.php/Main/CompatibilityList Dreamcast-Scene Playability List] * [http://web.archive.org/web/20080507055905/http://www.screamcast.net/boards/viewtopic.php?t=152 Official Compatibility List ''(Archived)] * [http://web.archive.org/web/20080528233720/screamcast.net/boards/viewtopic.php?t=172 Screamcast NeoDC Page ''(Archived)] 41361751abf1e2e6b30b58fc27ec7815b1ecc3f9 NEO4All 0 868 2697 2021 2023-03-03T22:09:36Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | NEO4ALL |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:neo4all.png|thumb|280px| Metal Slug 2]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://chui.dcemu.co.uk/index.html Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Release<br/>Candidate 4}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-rc4.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/04/2007}}} |- style="background:#ffffff" |Author || {{{author|[[Chui]]}}} |- style="background:#ffffff" |Based on || {{{original|[[NeoCD/SDL_DC|NeoCD DC]]/<br/>[http://gngeo.berlios.de/ GnGeo]/<br/>[http://pacifi3d.retrogames.com/neocdsdl/index.html NeoCD/SDL]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|NeoGeoCD}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|''Unknown''}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50/60Hz}}} |} ==History== Neo4All is an open-source NeoGeoCD emulator for Dreamcast brought to you by [[Chui]] and [[Fox68k]], and it's by far the best NeoGeoCD emulator for Dreamcast. Using code from the GnGeo project, it's a port of Fabrice Martinez' NeoCD emulator to the Dreamcast based on Fosters' NeoCD/SDL. The current release features amazing compatibility and full speed emulation with full CDDA and SFX. It has a brandnew GUI with customizable controls and even a standalone CD option (so you can burn the emulator and your game to 1 disc). [[Image:Artfight.gif| Art of Fighting]] ===Features=== * Full Speed Emulation * High Compatibility * Disc Swap with NeoGeoCD games ''(rips) * Full VMU Support * Region Selection * 2 Player Support * Nice GUI with Music * Customizable Controls * Safe Reset Function * Standalone CD Feature (the emu + your game on 1 CD) * Low level CD-ROM access for fast CD swap * Main CPU Motorola 68000 * FAME emulation library by Fox68k * Sound CPU Zilog Z80 * FAZE Z80 emulation core by Fox68k * Overclock & Underclock Options for both CPUs * NeoGeo CD Video Display Processor * Custom PowerVR2 based engine by Chui * Tile caching. * SQ data transfer. * Optional bilinear filtering * YM2610 FM sound emulation. [[Image:Puzzbob.gif| Puzzle Bobble]] [[Image:Aerofight.gif| Aero Fighters]] ===To be implemented=== * Arcade Stick (C+Z) support * Button config for menu options. * Ability to read Official Neo CD disks as opposed to rips. * Increased CDDA compatibility ===NeoGeo AES/MVS=== There's also a fork of this emulator that plays AES/MVS cartridge games called [[AES4ALL]] ''(a.k.a. NEO4ALL/AES)''. ==Downloads== *Neo4all RC-4 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-rc4.rar Plain files] *Neo4all RC-4 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-rc4.tar.bz2 Source] *Neo4all RC-3 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-rc3.rar Plain files] - 04/04/2007 *Neo4all RC-3 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-rc3-fix.tar.bz2 Source] - 04/04/2007 *Neo4all RC-1 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-rc1.rar Plain files] - 09/03/2006 *Neo4all RC-1 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-rc1.tar.bz2 Source] - 09/03/2006 *Neo4all Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-beta4.rar Plain Files] *Neo4all Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-beta4.tar.bz2 Source] *Neo4all Beta 3 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-beta3.rar Plain Files] *Neo4all Beta 3 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-beta3.tar.bz2 Source] *Neo4all Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-beta2.rar Plain Files] *Neo4all Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-beta2.tar.bz2 Source] *Neo4all Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-beta-one.rar Plain Files] *Neo4all Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-beta-one.rar Source] *Neo4all Alpha 2 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-alpha-two.rar Plain Files] *Neo4all Alpha 2 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-alpha-two.rar Source] *Neo4all Alpha 1 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-alpha-one.rar Plain Files] *Neo4all Alpha 1 - [https://files.dcemulation.org/software/dreamcast/emulators/neo4all/neo4all-src-alpha-one.rar Source] ==Burning== All you need is to have the NeoGeoCD BIOS (NEOCD.BIN, 512 KByte ''- not provided'' ) in your root folder (along with the emulator itself of course): * C:\BootDreams\Neo4All\NEOCD.BIN\ if using [[BootDreams]] or * C:\Sbinducr\Inducer\NEOCD.BIN\ if using [[Selfboot Inducer]] That's it. ==Links== * [http://chui.dcemu.co.uk/ Chui's Site] * [http://www.m68k.com/fame/ FAME Site] ==Compatibility== ''The following games have been reported to work (As standalone game/emulator single discs): * 2020 Super Baseball * 3 Count Bout * Aero Fighters 2 * Aggressors of Dark Kombat * Alpha Mission 2 * Art of Fighting 2 * Baseball Stars 2 * Baseball Stars Professional * Blues Journey * Breakers * Crossed Swords * Crossed Swords 2 * Cyber Lip * Drift Out * Fatal Fury * Football Frenzy * Galaxy Fight * Ghost Pilots * Ironclad * Kabuki Klash * King Of Fighters 94 * King Of Fighters 95 * King of Fighters 96 * King of Fighters 97 * King of Fighters 98 * King of Fighters 99 * Last Hope * League Bowling * Magical Drop 2 * Magician Lord * Master of Syougi * Metal Slug * Metal Slug 2 * Nam 1975 * Neo Turf Masters * Ninja Commando * Ninja Master's * Pulstar * Puzzle Bobble * Quest of Jongmaster * Quiz King of Fighters * Ragnagard * Rally Chase * Real Bout Fatal Fury * Robo Army * Samurai Shodown II * Samurai Shodown IV * Sengoku * Sengoku 2 * Soccer Brawl * Street Slam * Super Sidekicks 2 * Super Spy * Top Hunter * Top Players Golf * Twinkle Starsprites * ViewPoint * Windjammers * World Heroes * World Heroes 2 Jet * World Heroes Perfect * Zintrick [[Category:Emulator]] ab8330466f3720733535fafee20eb5ccd4da7204 DREAMNEOCD 0 134 2698 844 2023-03-03T22:12:00Z Unknown user 0 wikitext text/x-wiki Dream neo cd is a based of my old port neogeo cd sdl You can find the src at https://github.com/ianmicheal/DREAMNEO-CD-1.0 [https://files.dcemulation.org/software/dreamcast/emulators/dreamneocd/DREAMNEO-CD-1.0-master.zip Download Locally] Dream neo cd for DreamCast V 1.0 [http://Youtube Youtube]https://youtu.be/H3_0t7dvz1I Major update this is neogeo cd emulator for dreamcast it can selfboot games and run real neogeo cd games on dreamcast It can also be used from dreamshell and a sd card with out cdda In 2004 I ported this to dreamcast the first working neogeo cd emulator for our beloved console It can play real neogeo cd games and also selfboot on the same cdi Based on fosters neogeocd/sdl https://github.com/joolswills/neocdsdl Disclaimer This program requires a system rom (bios) from the original Neogeo CD console to function. This code is copyrighted and therefore you are not entitled to a copy unless you own an original Neogeo CD console. Do not enquire where to find this file. Suffice to say that it should be called neocd.bin and should be 512kb in size. A smaller version of this bios file exists on the internet, however this will no longer work with DREAMNEO CD(v 1.0 onwards) DREAMNEO-CD-1.0 IS FREE, SOURCE CODE IS FREE. SELLING IS NOT ALLOWED. YOU CAN REUSE SOURCE CODE AND TECHNICAL KNOWLEDGE AS LONG AS IT IS NOT FOR COMMERCIAL PURPOSES. Acknowledgements (in no particular order) Beta testers deluxux Anthony817 Freak dave bjankins1 Mathieu Peponas - The GNGEO source was really useful for information and was really open about licencing files to be compatible with NeoCD/SDL. Mrneo240 Coding advice inspiration Just a fantastic coder and freind https://gitlab.com/HaydenKow/nuquake troy GPF Kos cdda sound help support debugging SDL Stephane Dallongeville - C68K (68000 CPU emulator) version 0.80 Copyright 2003-2004 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Stephane Dallongeville - CZ80 (Z80 CPU emulator) version 0.9 Copyright 2004-2005 Stephane Dallongeville (http://gens.consolemul.com then go to the forum). Moopthehedgehog Memfunctions coding advice just a great guy know's his stuff https://github.com/Moopthehedgehog Thanks to all at the simulant discord for there help freindship advice https://gitlab.com/simulant/simulant A general purpose game engine for Linux, Android and the SEGA Dreamcast! https://discordapp.com/invite/TRx94EV A place for dreamcast dev's of all types and to help with the engine https://simulant-engine.appspot.com/ Thanks to every one at dctalk forum for love and support on all my projects https://www.dreamcast-talk.com/forum/index.php quzar for being the best person to have on my team in 2004 lot's code fixes and fixed a lot of the memory functions and rendering It's now fully back from the dead again after you brought back from the dead dead thank you :) The MAME team - For an incredible emulator, a source tree full of useful information, and for sucking away more of my time than any other computer program in years 8) Sam Lantinga et al. - For the amazing libSDL cross-platform C library. (Only sound is used nothing else) DC Scene - Thanks for the help translating asm to C Black aura :) Everyone Else - Thanks for taking an interest. 43a311467239b614df9cbe39f34ac528e3b6f71f PCSX-DC 0 869 2699 2023 2023-03-03T22:14:34Z Unknown user 0 wikitext text/x-wiki == PCSX-DC == {{Infobox_Emulator_Information| name=PCSX-DC| image=no image| homepage=[http://www.pcsx.net/ Homepage]| version=1.4| downloads=[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-DJ.zip DiscJuggler (NTSC)]<br/>[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-DJ.zip DiscJuggler (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-Nero.zip Nero (NTSC)]<br/ >[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-Nero.zip Nero (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-Plain-NTSC.zip Plain Files (NTSC)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-PlainFiles.zip Plain Files (PAL)]<br />| release date=10/31/2002| author=[[Mark Grilenkov]]| original=PCSX<br/>(PCSX-Team)| systems=PlayStation| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} PCSX-DC is the first homebrew Playstation emulator for the Dreamcast and shows that large scale PlayStation emulation on Dreamcast IS possible. It is a port of the popular PC PlayStation emulator PCSX. Right now speeds are not playable and there is no sound. However it is a great proof of concept. The Dreamcast port of PCSX was done by [[Mark Grilenkov]]. ==Features== *Supports .bin image files (This is the only thing it supports) *Built in HLE bios (Official Sony bios also supported) *PAL and NTSC support ==Historical files== *[https://files.dcemulation.org/software/dreamcast/emulators/pcsxdc/pcsxdc-1.3a.zip PCSXDC 1.3a Plain Files] f0bfb7b02f88b1c2815a7aa6699c997aa97117a5 2700 2699 2023-03-03T22:21:42Z Unknown user 0 wikitext text/x-wiki == PCSX-DC == {{Infobox_Emulator_Information| name=PCSX-DC| image=no image| homepage=[http://www.pcsx.net/ Homepage]| version=1.4| downloads=[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-DJ.zip DiscJuggler (NTSC)]<br/>[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-DJ.zip DiscJuggler (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-Nero.zip Nero (NTSC)]<br/ >[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-Nero.zip Nero (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-Plain-NTSC.zip Plain Files (NTSC)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-PlainFiles.zip Plain Files (PAL)]<br />| release date=10/31/2002| author=[[Mark Grilenkov]]| original=PCSX<br/>(PCSX-Team)| systems=PlayStation| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} PCSX-DC is the first homebrew Playstation emulator for the Dreamcast and shows that large scale PlayStation emulation on Dreamcast IS possible. It is a port of the popular PC PlayStation emulator PCSX. Right now speeds are not playable and there is no sound. However it is a great proof of concept. The Dreamcast port of PCSX was done by [[Mark Grilenkov]]. ==Features== *Supports .bin image files (This is the only thing it supports) *Built in HLE bios (Official Sony bios also supported) *PAL and NTSC support ==Historical files== *[https://files.dcemulation.org/software/dreamcast/emulators/pcsxdc/pcsxdc-1.3a.zip PCSXDC 1.3a Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/pcsxdc/Pcsxdc-1.3.sbi PCSXDC 1.3 SBI] 2455db695d459513b94e803d23471410e1eedb01 2727 2700 2023-03-03T23:43:24Z Unknown user 0 wikitext text/x-wiki == PCSX-DC == {{Infobox_Emulator_Information| name=PCSX-DC| image=no image| homepage=[http://www.pcsx.net/ Homepage]| version=1.4| downloads=[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-DJ.zip DiscJuggler (NTSC)]<br/>[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-DJ.zip DiscJuggler (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-Nero.zip Nero (NTSC)]<br/ >[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-Nero.zip Nero (PAL)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-Plain-NTSC.zip Plain Files (NTSC)]<br />[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-PlainFiles.zip Plain Files (PAL)]<br />| release date=10/31/2002| author=[[Mark Grilenkov]]| original=PCSX<br/>(PCSX-Team)| systems=PlayStation| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} PCSX-DC is the first homebrew Playstation emulator for the Dreamcast and shows that large scale PlayStation emulation on Dreamcast IS possible. It is a port of the popular PC PlayStation emulator PCSX. Right now speeds are not playable and there is no sound. However it is a great proof of concept. The Dreamcast port of PCSX was done by [[Mark Grilenkov]]. ==Features== *Supports .bin image files (This is the only thing it supports) *Built in HLE bios (Official Sony bios also supported) *PAL and NTSC support ==Historical files== *[https://files.dcemulation.org/software/dreamcast/emulators/pcsxdc/pcsxdc-1.3a.zip PCSXDC 1.3a Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/pcsxdc/Pcsxdc-1.3.sbi PCSXDC 1.3 SBI] BROKEN *[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-DJ.zip DiscJuggler (NTSC)] *[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-DJ.zip DiscJuggler (PAL)] *[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-NTSC-Nero.zip Nero (NTSC)] *[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-Nero.zip Nero (PAL)] *[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-Plain-NTSC.zip Plain Files (NTSC)] *[http://dcemulation.com/1-newsdump/emulators/PCSXDC-14a-PAL-PlainFiles.zip Plain Files (PAL)] {{DCWiki:BrokenInternalLinks}} 3903387e10162070173c0b551e3de0a5c6061d12 MamedDC 0 888 2701 2045 2023-03-03T22:30:59Z Unknown user 0 wikitext text/x-wiki Developer: MAMED Version: Beta 1 Last Updated: 07-17-01 MAMEDDC is an attempt to port MAME to the (wonderful) Dreamcast console by the same author who has ported it to many devices. Status: * Hundreds Of Games Supported * Sound ==Screenshots== <gallery> Image:Mamedc8.jpg Image:Mamedc6.jpg Image:Mamedc5.jpg </gallery> *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/mamedkit.zip Mamed Kit] A kit to help you burned these mamed's. *[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed1.rar DiskJuggler 1] MAMED Game Pack 1 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist1.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed2rar DiskJuggler 2] MAMED Game Pack 2 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist2.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed3.rar DiskJuggler 3] MAMED Game Pack 3 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist3.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed4.rar DiskJuggler 4] MAMED Game Pack 4 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist4.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed5.rar DiskJuggler 5] MAMED Game Pack 5 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist5.txt Games Supported]) (Games not Included) DiskJuggler 6 MAMED Game Pack 6 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist6.txt Games Supported]) (Games not Included) DiskJuggler 7 MAMED Game Pack 7 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist7.txt Games Supported]) (Games not Included) DiskJuggler 8 MAMED Game Pack 8 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist8.txt Games Supported]) (Games not Included) DiskJuggler 9 MAMED Game Pack 9 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist9.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed10.rar DiskJuggler 10] MAMED Game Pack 10 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist10.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed11.rar DiskJuggler 11] MAMED Game Pack 11 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist11.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed12.rar DiskJuggler 12] MAMED Game Pack 12 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist12.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed13.rar DiskJuggler 13] MAMED Game Pack 13 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist13.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed14.rar DiskJuggler 14] MAMED Game Pack 14 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist14.txt Games Supported]) (Games not Included) [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/mamed/Mamed15.rar DiskJuggler 15] MAMED Game Pack 15 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist15.txt Games Supported]) (Games not Included) 5a275aec5044a59b9521a24c1f29a021bde3190f 2702 2701 2023-03-03T22:32:26Z Unknown user 0 wikitext text/x-wiki Developer: MAMED Version: Beta 1 Last Updated: 07-17-01 MAMEDDC is an attempt to port MAME to the (wonderful) Dreamcast console by the same author who has ported it to many devices. Status: * Hundreds Of Games Supported * Sound ==Screenshots== <gallery> Image:Mamedc8.jpg Image:Mamedc6.jpg Image:Mamedc5.jpg </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/mamedkit.zip Mamed Kit] A kit to help you burned these mamed's. *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed1.rar DiskJuggler 1] MAMED Game Pack 1 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist1.txt Games Supported]) (Games not Included) [hhttps://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed2.rar DiskJuggler 2] MAMED Game Pack 2 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist2.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed3.rar DiskJuggler 3] MAMED Game Pack 3 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist3.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed4.rar DiskJuggler 4] MAMED Game Pack 4 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist4.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed5.rar DiskJuggler 5] MAMED Game Pack 5 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist5.txt Games Supported]) (Games not Included) DiskJuggler 6 MAMED Game Pack 6 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist6.txt Games Supported]) (Games not Included) DiskJuggler 7 MAMED Game Pack 7 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist7.txt Games Supported]) (Games not Included) DiskJuggler 8 MAMED Game Pack 8 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist8.txt Games Supported]) (Games not Included) DiskJuggler 9 MAMED Game Pack 9 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist9.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed10.rar DiskJuggler 10] MAMED Game Pack 10 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist10.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed11.rar DiskJuggler 11] MAMED Game Pack 11 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist11.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed12.rar DiskJuggler 12] MAMED Game Pack 12 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist12.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed13.rar DiskJuggler 13] MAMED Game Pack 13 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist13.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed14.rar DiskJuggler 14] MAMED Game Pack 14 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist14.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed15.rar DiskJuggler 15] MAMED Game Pack 15 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist15.txt Games Supported]) (Games not Included) 76e2b71fde21da017450d279af7acb33545aeeb8 2703 2702 2023-03-03T22:32:33Z Unknown user 0 /* Files */ wikitext text/x-wiki Developer: MAMED Version: Beta 1 Last Updated: 07-17-01 MAMEDDC is an attempt to port MAME to the (wonderful) Dreamcast console by the same author who has ported it to many devices. Status: * Hundreds Of Games Supported * Sound ==Screenshots== <gallery> Image:Mamedc8.jpg Image:Mamedc6.jpg Image:Mamedc5.jpg </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/mamedkit.zip Mamed Kit] A kit to help you burned these mamed's. *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed1.rar DiskJuggler 1] MAMED Game Pack 1 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist1.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed2.rar DiskJuggler 2] MAMED Game Pack 2 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist2.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed3.rar DiskJuggler 3] MAMED Game Pack 3 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist3.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed4.rar DiskJuggler 4] MAMED Game Pack 4 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist4.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed5.rar DiskJuggler 5] MAMED Game Pack 5 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist5.txt Games Supported]) (Games not Included) DiskJuggler 6 MAMED Game Pack 6 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist6.txt Games Supported]) (Games not Included) DiskJuggler 7 MAMED Game Pack 7 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist7.txt Games Supported]) (Games not Included) DiskJuggler 8 MAMED Game Pack 8 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist8.txt Games Supported]) (Games not Included) DiskJuggler 9 MAMED Game Pack 9 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist9.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed10.rar DiskJuggler 10] MAMED Game Pack 10 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist10.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed11.rar DiskJuggler 11] MAMED Game Pack 11 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist11.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed12.rar DiskJuggler 12] MAMED Game Pack 12 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist12.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed13.rar DiskJuggler 13] MAMED Game Pack 13 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist13.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed14.rar DiskJuggler 14] MAMED Game Pack 14 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist14.txt Games Supported]) (Games not Included) [https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed15.rar DiskJuggler 15] MAMED Game Pack 15 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist15.txt Games Supported]) (Games not Included) a014526d967b2c06ad37845b53d71152cb25462d 2704 2703 2023-03-03T22:33:04Z Unknown user 0 /* Files */ wikitext text/x-wiki Developer: MAMED Version: Beta 1 Last Updated: 07-17-01 MAMEDDC is an attempt to port MAME to the (wonderful) Dreamcast console by the same author who has ported it to many devices. Status: * Hundreds Of Games Supported * Sound ==Screenshots== <gallery> Image:Mamedc8.jpg Image:Mamedc6.jpg Image:Mamedc5.jpg </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/mamedkit.zip Mamed Kit] A kit to help you burned these mamed's. *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed1.rar DiskJuggler 1] MAMED Game Pack 1 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist1.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed2.rar DiskJuggler 2] MAMED Game Pack 2 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist2.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed3.rar DiskJuggler 3] MAMED Game Pack 3 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist3.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed4.rar DiskJuggler 4] MAMED Game Pack 4 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist4.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed5.rar DiskJuggler 5] MAMED Game Pack 5 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist5.txt Games Supported]) (Games not Included) *DiskJuggler 6 MAMED Game Pack 6 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist6.txt Games Supported]) (Games not Included) *DiskJuggler 7 MAMED Game Pack 7 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist7.txt Games Supported]) (Games not Included) *DiskJuggler 8 MAMED Game Pack 8 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist8.txt Games Supported]) (Games not Included) *DiskJuggler 9 MAMED Game Pack 9 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist9.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed10.rar DiskJuggler 10] MAMED Game Pack 10 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist10.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed11.rar DiskJuggler 11] MAMED Game Pack 11 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist11.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed12.rar DiskJuggler 12] MAMED Game Pack 12 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist12.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed13.rar DiskJuggler 13] MAMED Game Pack 13 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist13.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed14.rar DiskJuggler 14] MAMED Game Pack 14 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist14.txt Games Supported]) (Games not Included) *[https://files.dcemulation.org/software/dreamcast/emulators/mamed/Mamed15.rar DiskJuggler 15] MAMED Game Pack 15 ([https://files.dcemulation.org/software/dreamcast/emulators/mamed/gamelist15.txt Games Supported]) (Games not Included) 2bbee7a30d0d1bf5c47da7f8a991aa50b6777bab MameDC 0 893 2705 2050 2023-03-03T22:37:09Z Unknown user 0 wikitext text/x-wiki *Developer: Christophe Thibault - Site *Version: 0.4 *Last Updated: 07-21-01 *MAMEDC is an attempt to port MAME to the (wonderful) Dreamcast console. Status: * Some games work at 100% framerate, others are slower. * Supports the following drivers: PacMan, Arkanoid, Super Qix (bootleg), Psychic5, - Pang and Super Pang. * More drivers work but they are untested for now. * Basic (and buggy) sound support! * VERY unoptimized for now * James Surine provided working sound support! * added Ghosts'n Goblins and Commando drivers * now uses the TA hardware for displaying the screen so it's somewhat faster and looks way better * zip support added but it doesn't work right so keep on using unzipped roms * cd swapping code should be fixed (thanks to James Surine) * James also fixed a small bug in the sound code * zip support fixed! put all your zipped roms in the /roms/ folder * looks like some roms HAVE to be zipped otherwise they won't work * added bubble bobble, bombjack & contra drivers! * second controller support * added double dragon, double dragon 2, mspacman, galaga, 88 games, ikari warriors, gauntlet, gauntlet 2, 1941, ghouls'n ghosts (buggy), final fight (buggy) and strider (buggy) drivers * added gamelist scroll as the game list is getting huge :) * the auto frameskip sucked so it's now manual * more improvements in the graphic code. some drivers (like pang, contra and commando) are noticably faster * added progress indicator when loading roms * added 3rd button (B) support on the controllers * added antialias setting ==Screenshots== <gallery> Image:Mamedc.jpg Image:Mamedc4.jpg Image:Mamedc3.jpg Image:Mamedc2.jpg </gallery> =Downloads= *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc04-dj.zip Disk Juggler] *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc04-nero.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc04-bin.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc03-dj.zip Disk Juggler] Version 0.3 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc03-nero.zip Nero] Version 0.3 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc03-bin.zip Plain Files] Version 0.3 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc02-dj.zip Disk Juggler] Version 0.2 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc02-nero.zip Nero] Version 0.2 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc02-bin.zip Plain Files] Version 0.2 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc01-dj.zip Disk Juggler] Version 0.1 5415d3345ac53f162af2d0d1cb21b35abd6fd032 2706 2705 2023-03-03T22:37:23Z Unknown user 0 /* Downloads */ wikitext text/x-wiki *Developer: Christophe Thibault - Site *Version: 0.4 *Last Updated: 07-21-01 *MAMEDC is an attempt to port MAME to the (wonderful) Dreamcast console. Status: * Some games work at 100% framerate, others are slower. * Supports the following drivers: PacMan, Arkanoid, Super Qix (bootleg), Psychic5, - Pang and Super Pang. * More drivers work but they are untested for now. * Basic (and buggy) sound support! * VERY unoptimized for now * James Surine provided working sound support! * added Ghosts'n Goblins and Commando drivers * now uses the TA hardware for displaying the screen so it's somewhat faster and looks way better * zip support added but it doesn't work right so keep on using unzipped roms * cd swapping code should be fixed (thanks to James Surine) * James also fixed a small bug in the sound code * zip support fixed! put all your zipped roms in the /roms/ folder * looks like some roms HAVE to be zipped otherwise they won't work * added bubble bobble, bombjack & contra drivers! * second controller support * added double dragon, double dragon 2, mspacman, galaga, 88 games, ikari warriors, gauntlet, gauntlet 2, 1941, ghouls'n ghosts (buggy), final fight (buggy) and strider (buggy) drivers * added gamelist scroll as the game list is getting huge :) * the auto frameskip sucked so it's now manual * more improvements in the graphic code. some drivers (like pang, contra and commando) are noticably faster * added progress indicator when loading roms * added 3rd button (B) support on the controllers * added antialias setting ==Screenshots== <gallery> Image:Mamedc.jpg Image:Mamedc4.jpg Image:Mamedc3.jpg Image:Mamedc2.jpg </gallery> =Downloads= *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc04-dj.zip Disk Juggler] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc04-nero.zip Nero] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc04-bin.zip Plain Files] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc03-dj.zip Disk Juggler] Version 0.3 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc03-nero.zip Nero] Version 0.3 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc03-bin.zip Plain Files] Version 0.3 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc02-dj.zip Disk Juggler] Version 0.2 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc02-nero.zip Nero] Version 0.2 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc02-bin.zip Plain Files] Version 0.2 *[https://files.dcemulation.org/software/dreamcast/emulators/mamedc/mamedc01-dj.zip Disk Juggler] Version 0.1 f220643676ddb4202016fef7a829208b02b629bc MAME4All 0 896 2707 2054 2023-03-03T22:42:42Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=MAME4ALL| image=[[File:Mame4all.png]]<br /><br />[[File:Mame4allscreen.png|center|240px]]| homepage=[http://chui.dcemu.co.uk/ Homepage]| version=Beta 2| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/mame4all/mame4all-beta2.rar Plain Files]| release date=March 12th, 2008| author=[[Chui]]| original=[http://mamedev.org/ MAME]| systems=Multiple Arcade Cabinets 80's-90's| best=Yes| refreshrate=50Hz/60Hz| isactive=Unknown }} At the moment, MAME4ALL is beta stage, but hundreds of games work fine. '''Features: *[http://www.talfi.net/gp32_franxis/ MAME GP2X] adaptation to Dreamcast. *FAME Motorola 68000 core. *New FAZE Zilog Z80 core. *Around 1000 games supported. *Split into 3 parts: Aged, Classic and Gold. *Previous menu selection. *Auto-frameskip. *4 players support. *Hardware scaled blitter. *60-50Hz selection for PAL Dreamcasts. *Samples (.sam) support. *Two sound modes: normal and accurate. *CPU speed, sound, and joypad configuration options. *Improved compatibility over previous versions *Uses [http://maws.mameworld.info/maws/ MAME 0.34/0.35] romset like MAME GP2X 5.1, except for NeoGeo. *Uses standard [http://maws.mameworld.info/maws/ MAME naming] for zipped roms. ==Downloads== *Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/mame4all/mame4all-beta2.rar Plain Files] *Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/mame4all/mame4all-beta2-src.tar.bz2 Source] *Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/mame4all/mame4all-beta1.rar Plain Files] *Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/mame4all/mame4all-beta1-src.tar.bz2 Source] - 3/12/08 *Alpha 2 - [https://files.dcemulation.org/software/dreamcast/emulators/mame4all/mame4all-alpha2-src.tar.bz2 Source] - 4/25/06 [[Category:Emulator]] 66064d3d9f287136adb739b447ec9603b78312c0 Cpmame 0 897 2708 2055 2023-03-03T22:44:33Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=CPMAME| image=N/A| homepage=[http://siseinohito.tripod.co.jp/ Homepage]| version=???| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/cpmame/cpmame.zip Plain Files]| release date=Unknown| author=Sisei| original=MAME | systems=MAME| best=No| refreshrate=''Unknown| isactive=''Unknown| }} Unnofficial Mame for DC / CPMAME Developer: Sisei Version: CP1MAME37b16 Last Updated: May, 2002 Description: A port of MAME. =Downloads= * CP1MAME37b16 - [https://files.dcemulation.org/software/dreamcast/emulators/cpmame/cpmame.zip Plain Files] 779kb [[category:emulator]] 5318dd76d3851ba6d8fd542b96c106d6dbaedcf0 LaserDC 0 898 2709 2056 2023-03-03T22:45:33Z Unknown user 0 wikitext text/x-wiki Developer: [http://devcast.wolfnet.org/ ss_teven - DevCast] Version: v0.13 r1 Last Updated: 11-01-01 LaserDC is a Midway Z80 Emulator for the Sega Dreamcast console system. Its currently in beta-stage so bugs do exist. This emulates the following arcade games: * Space Invaders * Space Invaders Deluxe * Lunar Rescue * Galaxy Wars * Space Attack II * Destination Earth * Invaders Revenge * Super Earth Invasion * Boot Hill * Space Invaders (CV Ver) * Cosmic Monsters * Laser * Space King * Check Mate * Space War 3 * Clowns * Space Invaders (TV Version) * 4 Player Bowling Alley * Moon Base * Space Invaders Part II * Lupin III * Space Fever * Space Attack * Space King Part 2 * Test * Star Wars * Space Chaser * Amazing Maze * Ozma Wars * Ozma Wars (set 2) * Solar Fight * Super Invaders * Super Invaders (EMAG) * Super Invaders (Zenitone-Microsec) [https://files.dcemulation.org/software/dreamcast/emulators/laserdc/laserdcr1.zip Plain Files] da0908bcf5d6616df1aaaa544333c396b4d3380a System16 0 899 2710 2057 2023-03-03T22:52:20Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | System16 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|''Image<br/>not available''}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://dev.dcemulation.org/mamed/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/emulators/system16/SYSTEM16_BETA2.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|01/13/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Reaper2K2]]}}} |- style="background:#ffffff" |Based on || {{{original|MAME<br/>''(Unknown version)''}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|System 16 Arcade}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|''Unknown''}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown''}}} |} ==History== This is a port of the System 16 code from MAME. It allows for the emulation of System 16 games on your Dreamcast. ===Features=== * Fullscreen position fixed. * Sound quality improved. * Sound tick, and buzzing, fixed in most games. * Fullspeed without sound. * New games supported. ''(from last ver.)'' ==Downloads== * Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/system16/SYSTEM16_BETA2.zip Plainfiles] - 10/03/2003 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/system16/SYSTEM16_BETA1.zip Plainfiles] - ''Unknown release date 7f20003c5c8df0c95588ca01aec0441a90366548 2711 2710 2023-03-03T22:53:03Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | System16 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|''Image<br/>not available''}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://dev.dcemulation.org/mamed/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/emulators/system16/SYSTEM16_BETA2.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|01/13/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Reaper2K2]]}}} |- style="background:#ffffff" |Based on || {{{original|MAME<br/>''(Unknown version)''}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|System 16 Arcade}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|''Unknown''}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown''}}} |} This is a port of the System 16 code from MAME. It allows for the emulation of System 16 games on your Dreamcast. ===Features=== * Fullscreen position fixed. * Sound quality improved. * Sound tick, and buzzing, fixed in most games. * Fullspeed without sound. * New games supported. ''(from last ver.)'' ==Downloads== * Beta 2 - [https://files.dcemulation.org/software/dreamcast/emulators/system16/SYSTEM16_BETA2.zip Plainfiles] - 10/03/2003 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/system16/SYSTEM16_BETA1.zip Plainfiles] - ''Unknown release date a53bd593d261ccb4d7e277c2c0b0a2081276764a Single-game MAME releases 0 930 2712 2095 2023-03-03T22:57:00Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Single-game MAME| image=| homepage=''N/A| version=''N/A| downloads=[[#Downloads|Below]]| release date=''Various| author=''Various| original=[http://mamedev.org/ MAME]| systems=Various Arcade| best=Probably not,<br/>check [[MAME4ALL]]| refreshrate=50Hz/60Hz| isactive=No| }} ==History== These single game MAME release were developed by James Surine, ice88, IMR, and Metafox. [[James Surine]] ported MAME v0.37b to the DC, and [[ice88]] ported MAME v0.72. [http://imrtechnology.ngemu.com/ IMR], and [[MetaFox]], improved upon their source to release several single game emulators (and a few multiple game emulators). The following games, or collection of games, were released in '.sbi' form. You can add as many as you wish, or can fit, onto a single disc using [http://dchelp.net/tag/selfboot-inducer/ Selfboot Inducer]. ==Downloads== * 1943 ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-1943.sbi SBI] * Araknoid ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-arkanoid.sbi SBI] * Bagman ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-bagman2.sbi SBI] * Bubble Bobble ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-BubbleBobble.sbi SBI] * Cadillacs & Dinosaurs ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-CadillacsDinos.sbi SBI] * CPS1 Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SBI-cps1dc.sbi SBI], [http://www.dcemulation.org/files/emulators/cps1dc.zip Plain] - ''pack that runs CPS1 games'' * Double Dragon ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_DDRAGON.sbi SBI] * Frogger ** by JWT - [http://www.dcemulation.org/files/sbi3.0/JWT_FroggerSGA_CG.sbi SBI] * Galaga ** by IMR - [http://www.dcemulation.org/files/sbi3.0/Galaga_bO.sbi SBI] * Gradius III ** by ? - [http://www.dcemulation.org/files/sbi3.0/SGA-GradiusIII.sbi SBI] * Green Beret ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-GreenBeret.sbi SBI] * Gunsmoke ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Gunsmoke.sbi SBI] * Haunted Castle ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-HauntedCastle_CG.sbi SBI] * Ladybug ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-ladybug.sbi SBI] * Mustache boy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-mustache.sbi SBI] * Neck & Neck ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-neckneck.sbi SBI] * Pacman Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/IMR-Pacmanpack.sbi SBI], [http://www.dcemulation.org/files/emulators/pacmanpack.zip Plain] - ''(Pac-Man, Jump Shot, Lizard Wizard, Magic Brush, Make Trax (set 1), Mr. TNT, Ms. Pac Man Attacks, Ms. Pac-Man, Puckman) * Paperboy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-paperboy.sbi SBI] * Parodius ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Parodius.sbi SBI] * Pengo ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-pengo2.sbi SBI] * Perfect Billiard ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-PerfectBilliard_CG.sbi SBI] * Popeye ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-popeye2.sbi SBI] * Puyo Puyo ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-PuyoPuyo.sbi SBI] * Rastan ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_Rastan.sbi SBI] * Robocop ** by IMR - [http://www.dcemulation.org/files/sbi3.0/RobocopSmooth_CG.sbi SBI] * Rygar ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Rygar.sbi SBI] * Scramble ** by IMR - [http://www.dcemulation.org/files/sbi3.0/sga-scramble.sbi SBI] * Shinobi ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Shinobi.sbi SBI] * Simpsons ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_SIMPSONS.sbi SBI] * SimVen ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SimVenv2_CG.sbi SBI] - ''(Simpsons, Vendetta) ** [http://www.dcemulation.org/files/sbi3.0/SBI-simpsonsvendetta.sbi SBI], [http://www.dcemulation.org/files/emulators/simpsonsvendetta.zip Plain] * Sky Skipper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-skyskipr.sbi SBI] * Street Fighter II ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Sf2dc.sbi SBI] * Super Sprint ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-ssprint.sbi SBI] * Taito Hits ** by IMR - [http://www.dcemulation.org/files/sbi3.0/TaitoHits_CG.sbi SBI], [http://www.dcemulation.org/files/emulators/taitopack.zip Plain], [http://www.dcemulation.org/phpBB/viewtopic.php?t=38971 Info] - ''(New Zealand story, Arkanoid 2, Extermination, Insector X, kageki, Chuka Taisen, Dr. Toppels Adventure, Plump pop) * Tapper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-tapper.sbi SBI] * T.M.N.T. ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Tmnt.sbi SBI] * Vendetta ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_VENDETTA.sbi SBI] * Willow ** by IMR - [http://www.dcemulation.org/files/sbi3.0/sga-willowwip.sbi SBI] * Wonderboy ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Wonderboy.sbi SBI] * X-Men ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_XMEN.sbi SBI] * Xevious ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Xevious.sbi SBI] * Xybots ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SGA-Xybots.sbi SBI] * Yie Ar Kung Fu ** by JWT - [http://www.dcemulation.org/files/sbi3.0/JWT_YieArSGA_CG.sbi SBI] ==Links== * DEAD LINK <s>[http://imrtechnology.ngemu.com/sga.htm More SGA Releases]</s> ''via IMR 64511dfc5d93d438186f5e8a42371c793b0d406a 2713 2712 2023-03-03T23:04:55Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Single-game MAME| image=| homepage=''N/A| version=''N/A| downloads=[[#Downloads|Below]]| release date=''Various| author=''Various| original=[http://mamedev.org/ MAME]| systems=Various Arcade| best=Probably not,<br/>check [[MAME4ALL]]| refreshrate=50Hz/60Hz| isactive=No| }} ==History== These single game MAME release were developed by James Surine, ice88, IMR, and Metafox. [[James Surine]] ported MAME v0.37b to the DC, and [[ice88]] ported MAME v0.72. [http://imrtechnology.ngemu.com/ IMR], and [[MetaFox]], improved upon their source to release several single game emulators (and a few multiple game emulators). The following games, or collection of games, were released in '.sbi' form. You can add as many as you wish, or can fit, onto a single disc using [http://dchelp.net/tag/selfboot-inducer/ Selfboot Inducer]. ==Downloads== * 1943 ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-1943.sbi SBI] * Araknoid ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-arkanoid.sbi SBI] * Bagman ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-bagman2.sbi SBI] * Bubble Bobble ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-BubbleBobble.sbi SBI] * Cadillacs & Dinosaurs ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-CadillacsDinos.sbi SBI] * CPS1 Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SBI-cps1dc.sbi SBI], [http://www.dcemulation.org/files/emulators/cps1dc.zip Plain] - ''pack that runs CPS1 games'' * Double Dragon ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_DDRAGON.sbi SBI] * Frogger ** by JWT - [http://www.dcemulation.org/files/sbi3.0/JWT_FroggerSGA_CG.sbi SBI] * Galaga ** by IMR - [http://www.dcemulation.org/files/sbi3.0/Galaga_bO.sbi SBI] * Gradius III ** by ? - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-GradiusIII.sbi SBI] * Green Beret ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-GreenBeret.sbi SBI] * Gunsmoke ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Gunsmoke.sbi SBI] * Haunted Castle ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-HauntedCastle_CG.sbi SBI] * Ladybug ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-ladybug.sbi SBI] * Mustache boy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-mustache.sbi SBI] * Neck & Neck ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-neckneck.sbi SBI] * Pacman Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/IMR-Pacmanpack.sbi SBI], [http://www.dcemulation.org/files/emulators/pacmanpack.zip Plain] - ''(Pac-Man, Jump Shot, Lizard Wizard, Magic Brush, Make Trax (set 1), Mr. TNT, Ms. Pac Man Attacks, Ms. Pac-Man, Puckman) * Paperboy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-paperboy.sbi SBI] * Parodius ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Parodius.sbi SBI] * Pengo ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-pengo2.sbi SBI] * Perfect Billiard ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-PerfectBilliard_CG.sbi SBI] * Popeye ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-popeye2.sbi SBI] * Puyo Puyo ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-PuyoPuyo.sbi SBI] * Rastan ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_Rastan.sbi SBI] * Robocop ** by IMR - [http://www.dcemulation.org/files/sbi3.0/RobocopSmooth_CG.sbi SBI] * Rygar ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Rygar.sbi SBI] * Scramble ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/sga-scramble.sbi SBI] * Shinobi ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Shinobi.sbi SBI] * Simpsons ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_SIMPSONS.sbi SBI] * SimVen ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SimVenv2_CG.sbi SBI] - ''(Simpsons, Vendetta) ** [http://www.dcemulation.org/files/sbi3.0/SBI-simpsonsvendetta.sbi SBI], [http://www.dcemulation.org/files/emulators/simpsonsvendetta.zip Plain] * Sky Skipper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-skyskipr.sbi SBI] * Street Fighter II ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Sf2dc.sbi SBI] * Super Sprint ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-ssprint.sbi SBI] * Taito Hits ** by IMR - [http://www.dcemulation.org/files/sbi3.0/TaitoHits_CG.sbi SBI], [http://www.dcemulation.org/files/emulators/taitopack.zip Plain], [http://www.dcemulation.org/phpBB/viewtopic.php?t=38971 Info] - ''(New Zealand story, Arkanoid 2, Extermination, Insector X, kageki, Chuka Taisen, Dr. Toppels Adventure, Plump pop) * Tapper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-tapper.sbi SBI] * T.M.N.T. ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Tmnt.sbi SBI] * Vendetta ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_VENDETTA.sbi SBI] * Willow ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/sga-willowwip.sbi SBI] * Wonderboy ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Wonderboy.sbi SBI] * X-Men ** by ice88 - [http://www.dcemulation.org/files/sbi3.0/m2_XMEN.sbi SBI] * Xevious ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Xevious.sbi SBI] * Xybots ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Xybots.sbi SBI] * Yie Ar Kung Fu ** by JWT - [http://www.dcemulation.org/files/sbi3.0/JWT_YieArSGA_CG.sbi SBI] ==Links== * DEAD LINK <s>[http://imrtechnology.ngemu.com/sga.htm More SGA Releases]</s> ''via IMR 3bab46473f6c238a5b295d042b8934ba7beb820f 2714 2713 2023-03-03T23:13:00Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Single-game MAME| image=| homepage=''N/A| version=''N/A| downloads=[[#Downloads|Below]]| release date=''Various| author=''Various| original=[http://mamedev.org/ MAME]| systems=Various Arcade| best=Probably not,<br/>check [[MAME4ALL]]| refreshrate=50Hz/60Hz| isactive=No| }} ==History== These single game MAME release were developed by James Surine, ice88, IMR, and Metafox. [[James Surine]] ported MAME v0.37b to the DC, and [[ice88]] ported MAME v0.72. [http://imrtechnology.ngemu.com/ IMR], and [[MetaFox]], improved upon their source to release several single game emulators (and a few multiple game emulators). The following games, or collection of games, were released in '.sbi' form. You can add as many as you wish, or can fit, onto a single disc using [http://dchelp.net/tag/selfboot-inducer/ Selfboot Inducer]. ==Downloads== * 1943 ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-1943.sbi SBI] * Araknoid ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-arkanoid.sbi SBI] * Bagman ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-bagman2.sbi SBI] * Bubble Bobble ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-BubbleBobble.sbi SBI] * Cadillacs & Dinosaurs ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-CadillacsDinos.sbi SBI] * CPS1 Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SBI-cps1dc.sbi SBI], [http://www.dcemulation.org/files/emulators/cps1dc.zip Plain] - ''pack that runs CPS1 games'' * Double Dragon ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_DDRAGON.sbi SBI] * Frogger ** by JWT - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/JWT_FroggerSGA_CG.sbi SBI] * Galaga ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/Galaga_bO.sbi SBI] * Gradius III ** by ? - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-GradiusIII.sbi SBI] * Green Beret ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-GreenBeret.sbi SBI] * Gunsmoke ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Gunsmoke.sbi SBI] * Haunted Castle ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-HauntedCastle_CG.sbi SBI] * Ladybug ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-ladybug.sbi SBI] * Mustache boy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-mustache.sbi SBI] * Neck & Neck ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-neckneck.sbi SBI] * Pacman Pack ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/IMR-Pacmanpack.sbi SBI], [http://www.dcemulation.org/files/emulators/pacmanpack.zip Plain] - ''(Pac-Man, Jump Shot, Lizard Wizard, Magic Brush, Make Trax (set 1), Mr. TNT, Ms. Pac Man Attacks, Ms. Pac-Man, Puckman) * Paperboy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-paperboy.sbi SBI] * Parodius ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Parodius.sbi SBI] * Pengo ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-pengo2.sbi SBI] * Perfect Billiard ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-PerfectBilliard_CG.sbi SBI] * Popeye ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-popeye2.sbi SBI] * Puyo Puyo ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-PuyoPuyo.sbi SBI] * Rastan ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_Rastan.sbi SBI] * Robocop ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/RobocopSmooth_CG.sbi SBI] * Rygar ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Rygar.sbi SBI] * Scramble ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/sga-scramble.sbi SBI] * Shinobi ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Shinobi.sbi SBI] * Simpsons ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_SIMPSONS.sbi SBI] * SimVen ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SimVenv2_CG.sbi SBI] - ''(Simpsons, Vendetta) ** [http://www.dcemulation.org/files/sbi3.0/SBI-simpsonsvendetta.sbi SBI], [http://www.dcemulation.org/files/emulators/simpsonsvendetta.zip Plain] * Sky Skipper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-skyskipr.sbi SBI] * Street Fighter II ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Sf2dc.sbi SBI] * Super Sprint ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-ssprint.sbi SBI] * Taito Hits ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/TaitoHits_CG.sbi SBI], [http://www.dcemulation.org/files/emulators/taitopack.zip Plain], [http://www.dcemulation.org/phpBB/viewtopic.php?t=38971 Info] - ''(New Zealand story, Arkanoid 2, Extermination, Insector X, kageki, Chuka Taisen, Dr. Toppels Adventure, Plump pop) * Tapper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-tapper.sbi SBI] * T.M.N.T. ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Tmnt.sbi SBI] * Vendetta ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_VENDETTA.sbi SBI] * Willow ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/sga-willowwip.sbi SBI] * Wonderboy ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Wonderboy.sbi SBI] * X-Men ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_XMEN.sbi SBI] * Xevious ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Xevious.sbi SBI] * Xybots ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Xybots.sbi SBI] * Yie Ar Kung Fu ** by JWT - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/JWT_YieArSGA_CG.sbi SBI] ==Links== * DEAD LINK <s>[http://imrtechnology.ngemu.com/sga.htm More SGA Releases]</s> ''via IMR b48467381dd1123e0cf5da2a7a6f5bc2560d990c 2730 2714 2023-03-03T23:44:52Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Single-game MAME| image=| homepage=''N/A| version=''N/A| downloads=[[#Downloads|Below]]| release date=''Various| author=''Various| original=[http://mamedev.org/ MAME]| systems=Various Arcade| best=Probably not,<br/>check [[MAME4ALL]]| refreshrate=50Hz/60Hz| isactive=No| }} ==History== These single game MAME release were developed by James Surine, ice88, IMR, and Metafox. [[James Surine]] ported MAME v0.37b to the DC, and [[ice88]] ported MAME v0.72. [http://imrtechnology.ngemu.com/ IMR], and [[MetaFox]], improved upon their source to release several single game emulators (and a few multiple game emulators). The following games, or collection of games, were released in '.sbi' form. You can add as many as you wish, or can fit, onto a single disc using [http://dchelp.net/tag/selfboot-inducer/ Selfboot Inducer]. ==Downloads== * 1943 ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-1943.sbi SBI] * Araknoid ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-arkanoid.sbi SBI] * Bagman ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-bagman2.sbi SBI] * Bubble Bobble ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-BubbleBobble.sbi SBI] * Cadillacs & Dinosaurs ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-CadillacsDinos.sbi SBI] * CPS1 Pack ** by IMR - [http://www.dcemulation.org/files/sbi3.0/SBI-cps1dc.sbi SBI], [http://www.dcemulation.org/files/emulators/cps1dc.zip Plain] - ''pack that runs CPS1 games'' * Double Dragon ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_DDRAGON.sbi SBI] * Frogger ** by JWT - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/JWT_FroggerSGA_CG.sbi SBI] * Galaga ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/Galaga_bO.sbi SBI] * Gradius III ** by ? - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-GradiusIII.sbi SBI] * Green Beret ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-GreenBeret.sbi SBI] * Gunsmoke ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Gunsmoke.sbi SBI] * Haunted Castle ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-HauntedCastle_CG.sbi SBI] * Ladybug ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-ladybug.sbi SBI] * Mustache boy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-mustache.sbi SBI] * Neck & Neck ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-neckneck.sbi SBI] * Pacman Pack ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/IMR-Pacmanpack.sbi SBI], [http://www.dcemulation.org/files/emulators/pacmanpack.zip Plain] - ''(Pac-Man, Jump Shot, Lizard Wizard, Magic Brush, Make Trax (set 1), Mr. TNT, Ms. Pac Man Attacks, Ms. Pac-Man, Puckman) * Paperboy ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-paperboy.sbi SBI] * Parodius ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Parodius.sbi SBI] * Pengo ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-pengo2.sbi SBI] * Perfect Billiard ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-PerfectBilliard_CG.sbi SBI] * Popeye ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-popeye2.sbi SBI] * Puyo Puyo ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-PuyoPuyo.sbi SBI] * Rastan ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_Rastan.sbi SBI] * Robocop ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/RobocopSmooth_CG.sbi SBI] * Rygar ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Rygar.sbi SBI] * Scramble ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/sga-scramble.sbi SBI] * Shinobi ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Shinobi.sbi SBI] * Simpsons ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_SIMPSONS.sbi SBI] * SimVen ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SimVenv2_CG.sbi SBI] - ''(Simpsons, Vendetta) ** [http://www.dcemulation.org/files/sbi3.0/SBI-simpsonsvendetta.sbi SBI], [http://www.dcemulation.org/files/emulators/simpsonsvendetta.zip Plain] * Sky Skipper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-skyskipr.sbi SBI] * Street Fighter II ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Sf2dc.sbi SBI] * Super Sprint ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-ssprint.sbi SBI] * Taito Hits ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/TaitoHits_CG.sbi SBI], [http://www.dcemulation.org/files/emulators/taitopack.zip Plain], [http://www.dcemulation.org/phpBB/viewtopic.php?t=38971 Info] - ''(New Zealand story, Arkanoid 2, Extermination, Insector X, kageki, Chuka Taisen, Dr. Toppels Adventure, Plump pop) * Tapper ** by MetaFox - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/meta-tapper.sbi SBI] * T.M.N.T. ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Tmnt.sbi SBI] * Vendetta ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_VENDETTA.sbi SBI] * Willow ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/sga-willowwip.sbi SBI] * Wonderboy ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Wonderboy.sbi SBI] * X-Men ** by ice88 - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/m2_XMEN.sbi SBI] * Xevious ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Xevious.sbi SBI] * Xybots ** by IMR - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/SGA-Xybots.sbi SBI] * Yie Ar Kung Fu ** by JWT - [https://files.dcemulation.org/software/dreamcast/emulators/mamesga/JWT_YieArSGA_CG.sbi SBI] ==Links== * DEAD LINK <s>[http://imrtechnology.ngemu.com/sga.htm More SGA Releases]</s> ''via IMR {{DCWiki:BrokenInternalLinks}} 496beaeef2cdadad4b92fc5ffe5385299c5de5e6 DreamPac 0 935 2715 2100 2023-03-03T23:26:43Z Unknown user 0 wikitext text/x-wiki *DreamPac *Developer: [http://www.ganksoft.com/ Ganksoft] *Version: 1.0 *Last Updated: 04-10-01 *Description: DreamPac is a Pacman hardware emulator for the Sega Dreamcast. It was written from scratch specifically for the Dreamcast platform. At the moment it plays the following games: *Pacman *Ms. Pacman *Crush Roller All games run at full speed and have full sound. More games may be added to this emulator at a later date (either Pacman clones or completely different games). [https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10dj.zip DJ image] [https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10ned.zip Nero DAO image] [https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10net.zip Nero TAO image] [https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10bif.zip Plain files] - v1.0b [https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10aif.zip Plain files] - v1.0a [https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10if.zip Plain files] - v1.0 <gallery> Image:Dreampac1.jpg Image:Dreampac2.jpg Image:Dreampac4.jpg Image:Dreampac3.jpg </gallery> b72760a0affc09345a7279a154e72c3135e0b2df 2716 2715 2023-03-03T23:27:02Z Unknown user 0 wikitext text/x-wiki *DreamPac *Developer: [http://www.ganksoft.com/ Ganksoft] *Version: 1.0 *Last Updated: 04-10-01 *Description: DreamPac is a Pacman hardware emulator for the Sega Dreamcast. It was written from scratch specifically for the Dreamcast platform. At the moment it plays the following games: *Pacman *Ms. Pacman *Crush Roller All games run at full speed and have full sound. More games may be added to this emulator at a later date (either Pacman clones or completely different games). <gallery> Image:Dreampac1.jpg Image:Dreampac2.jpg Image:Dreampac4.jpg Image:Dreampac3.jpg </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10dj.zip DJ image] *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10ned.zip Nero DAO image] *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10net.zip Nero TAO image] *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10bif.zip Plain files] - v1.0b *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10aif.zip Plain files] - v1.0a *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10if.zip Plain files] - v1.0 347994f79a39f80e4ae66874447374dab0fe644a 2717 2716 2023-03-03T23:28:02Z Unknown user 0 wikitext text/x-wiki *DreamPac *Developer: [http://www.ganksoft.com/ Ganksoft] *Version: 1.0 *Last Updated: 04-10-01 *Description: DreamPac is a Pacman hardware emulator for the Sega Dreamcast. It was written from scratch specifically for the Dreamcast platform. At the moment it plays the following games: *Pacman *Ms. Pacman *Crush Roller All games run at full speed and have full sound. More games may be added to this emulator at a later date (either Pacman clones or completely different games). <gallery> Image:Dreampac1.jpg Image:Dreampac2.jpg Image:Dreampac4.jpg Image:Dreampac3.jpg </gallery> ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10bif.zip Plain files] - v1.0b *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10aif.zip Plain files] - v1.0a *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10if.zip Plain files] - v1.0 *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10dj.zip DJ image] - v1.0 *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10ned.zip Nero DAO image] - v1.0 *[https://files.dcemulation.org/software/dreamcast/emulators/dreampac/dp10net.zip Nero TAO image] - v1.0 1bcc69a8cf29eda0d483995ce60e7465853e59f1 DCPhoenix 0 939 2718 2104 2023-03-03T23:30:16Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. Also plays Pleiads. Status: * VMU LCD Logo * Two Player Mode * Sound Support * Initial Pleiads emulation * Better video support. * Controller Support * Source Code Screen Shots: [[Image:Dcphoenix03.jpg]] [[Image:Dcphoenix02.jpg]] [[Image:Dcphoenix01.jpg]] [https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05DJ.zip Disk Jugger] Version 0.5 [https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05.zip Plain Files] Version 0.5 [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dc-phoenix04.zip Plain Files] Version 0.4 be4fc846489048ef91e2031bcb4af61fd2736587 2731 2718 2023-03-03T23:45:23Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. Also plays Pleiads. Status: * VMU LCD Logo * Two Player Mode * Sound Support * Initial Pleiads emulation * Better video support. * Controller Support * Source Code Screen Shots: <gallery> Image:Dcphoenix03.jpg Image:Dcphoenix02.jpg Image:Dcphoenix01.jpg </gallery> [https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05DJ.zip Disk Jugger] Version 0.5 [https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05.zip Plain Files] Version 0.5 [http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dc-phoenix04.zip Plain Files] Version 0.4 {{DCWiki:BrokenInternalLinks}} b3ff60793de1eef89298187d4db2a87fc94561c7 2739 2731 2023-03-03T23:59:52Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. Also plays Pleiads. Status: * VMU LCD Logo * Two Player Mode * Sound Support * Initial Pleiads emulation * Better video support. * Controller Support * Source Code Screen Shots: <gallery> Image:Dcphoenix03.jpg Image:Dcphoenix02.jpg Image:Dcphoenix01.jpg </gallery> *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05DJ.zip Disk Jugger] Version 0.5 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05.zip Plain Files] Version 0.5 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src05.zip Source] *[http://www.dcemulation.com/dl/dl.php3?url=files/emulators/dc-phoenix04.zip Plain Files] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src04.zip Source] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src03.zip Source] Version 0.3 {{DCWiki:BrokenInternalLinks}} 76eb258c61277f35e2b6762c7fd7e16518e5148e 2740 2739 2023-03-04T00:07:43Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. Also plays Pleiads. Status: * VMU LCD Logo * Two Player Mode * Sound Support * Initial Pleiads emulation * Better video support. * Controller Support * Source Code Screen Shots: <gallery> Image:Dcphoenix03.jpg Image:Dcphoenix02.jpg Image:Dcphoenix01.jpg </gallery> *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05DJ.zip Disk Jugger] Version 0.5 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05.zip Plain Files] Version 0.5 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src05.zip Source] *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix04.zip Plain Files] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src04.zip Source] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src03.zip Source] Version 0.3 {{DCWiki:BrokenInternalLinks}} 265b3e8eb50bc4d4334d5b9e70243cc98373eedd 2742 2740 2023-03-04T00:08:23Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.alienwebshop.com/pointblank/dc/ PointBlank] Version: 0.5 Last Updated: 04-25-01 It's a quick port of an old DOS/Allegro Phoenix arcade emulator. Also plays Pleiads. Status: * VMU LCD Logo * Two Player Mode * Sound Support * Initial Pleiads emulation * Better video support. * Controller Support * Source Code Screen Shots: <gallery> Image:Dcphoenix03.jpg Image:Dcphoenix02.jpg Image:Dcphoenix01.jpg </gallery> *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05DJ.zip Disk Jugger] Version 0.5 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix05.zip Plain Files] Version 0.5 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src05.zip Source] *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix04.zip Plain Files] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src04.zip Source] Version 0.4 *[https://files.dcemulation.org/software/dreamcast/emulators/dcphoenix/dc-phoenix-src03.zip Source] Version 0.3 d5f0aa2ecd69e39a219a87a9950faedf3b23fe49 DCSI 0 940 2719 2105 2023-03-03T23:31:41Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCSI| image=N/A| homepage=[http://www.finck.net/dcsi/ Homepage]| version=???| downloads=[http://www.dcemulation.org/files/software/dcsi_bin.zip Plain files]| release date=Unknown| author=D. Finck| original=N/A | systems=MAME| best=N/A| refreshrate=''Unknown| isactive=''Unknown| }} Developer: [http://www.finck.net/dcsi/ D. Finck] Version: 0.3? (0.4 is the final, which do we have here?) Last Updated: May 28, 2001 Description: A Space Invaders Emulator for the Dreamcast. =Downloads= * Version Unknown - [https://files.dcemulation.org/software/dreamcast/emulators/dcsi/dcsi_cdi.zip Disc Juggler image] * Version Unknown - [hhttps://files.dcemulation.org/software/dreamcast/emulators/dcsi/dcsi_bin.zip Plain files] [[category:emulator]] 2ad388113c0ce8bd1ff32d09c818d07193c53c70 2720 2719 2023-03-03T23:32:00Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCSI| image=N/A| homepage=[http://www.finck.net/dcsi/ Homepage]| version=???| downloads=[http://www.dcemulation.org/files/software/dcsi_bin.zip Plain files]| release date=Unknown| author=D. Finck| original=N/A | systems=MAME| best=N/A| refreshrate=''Unknown| isactive=''Unknown| }} Developer: [http://www.finck.net/dcsi/ D. Finck] Version: 0.3? (0.4 is the final, which do we have here?) Last Updated: May 28, 2001 Description: A Space Invaders Emulator for the Dreamcast. =Downloads= * Version Unknown - [https://files.dcemulation.org/software/dreamcast/emulators/dcsi/dcsi_cdi.zip Disc Juggler image] * Version Unknown - [https://files.dcemulation.org/software/dreamcast/emulators/dcsi/dcsi_bin.zip Plain files] [[category:emulator]] 10ad17f3cd9b4f3573a122e9a806fe80f82bc66a 2721 2720 2023-03-03T23:33:55Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=DCSI| image=N/A| homepage=[http://www.finck.net/dcsi/ Homepage]| version=???| downloads=[http://www.dcemulation.org/files/software/dcsi_bin.zip Plain files]| release date=Unknown| author=D. Finck| original=N/A | systems=MAME| best=N/A| refreshrate=''Unknown| isactive=''Unknown| }} Developer: [http://www.finck.net/dcsi/ D. Finck] Version: 0.3? (0.4 is the final, which do we have here?) Last Updated: May 28, 2001 Description: A Space Invaders Emulator for the Dreamcast. =Downloads= * 0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/dcsi/Dcsi.sbi SBI] * Version Unknown - [https://files.dcemulation.org/software/dreamcast/emulators/dcsi/dcsi_cdi.zip Disc Juggler image] * Version Unknown - [https://files.dcemulation.org/software/dreamcast/emulators/dcsi/dcsi_bin.zip Plain files] [[category:emulator]] c7e2db87293d89c97210c0393b9e0817f12c566c LynxMESS 0 905 2722 2064 2023-03-03T23:36:24Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=LynxMESS| image=N/A| homepage=Unknown| version=v1| downloads=[http://www.dcemulation.org/files/emulators/lynxdc.zip Plain files]| release date=Unknown| author=Ian Micheal| original=M.A.M.E. source code 0.71| systems=Atari Lynx| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ian Micheal Updated: 16-02-04 Description: An emulator for the handheld Atari Lynx. This is based off Ice88/Warmtoes work on M.E.S.S. and M.A.M.E. source code 0.71. It's running at about 36fps, which is a great speed for lynx. The only game tested is rygar, so other game speeds may vary. Speed: 70% Sound: Unknown Links: [http://www.dcemulation.org/phpBB/viewtopic.php?t=36622 Mess build Atari lynx release!] =Downloads= * v1 - [https://files.dcemulation.org/software/dreamcast/emulators/lynxmess/lynxdc.zip Plain files] * v1 - [http://www.dcemulation.org/files/sbi3.0/LynxDC_MESS_CG.sbi SBI file] [[category:emulator]] 7ae849b125c211aa4c8ac9c059d143631ff9f3c8 2733 2722 2023-03-03T23:46:22Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=LynxMESS| image=N/A| homepage=Unknown| version=v1| downloads=[http://www.dcemulation.org/files/emulators/lynxdc.zip Plain files]| release date=Unknown| author=Ian Micheal| original=M.A.M.E. source code 0.71| systems=Atari Lynx| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ian Micheal Updated: 16-02-04 Description: An emulator for the handheld Atari Lynx. This is based off Ice88/Warmtoes work on M.E.S.S. and M.A.M.E. source code 0.71. It's running at about 36fps, which is a great speed for lynx. The only game tested is rygar, so other game speeds may vary. Speed: 70% Sound: Unknown Links: [http://www.dcemulation.org/phpBB/viewtopic.php?t=36622 Mess build Atari lynx release!] =Downloads= * v1 - [https://files.dcemulation.org/software/dreamcast/emulators/lynxmess/lynxdc.zip Plain files] * v1 - [http://www.dcemulation.org/files/sbi3.0/LynxDC_MESS_CG.sbi SBI file] {{DCWiki:BrokenInternalLinks}} [[category:emulator]] fb656aa9fb499b43e6a9d4a10fb9290359733b43 OswanDC 0 906 2723 2065 2023-03-03T23:38:48Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.fmf.nl/~timo/project/oswandc.html Timo Laman] Updated: 08-21-02 A port of Oswan a Bandai WonderSwan (& WonderSwan Color) emulator '''SCREENSHOTS HOSTED AT DCHOMEBREW''' Speed: 99% Sound: 10% [https://files.dcemulation.org/software/dreamcast/emulators/oswandc/oswandc-bin-0.15.zip Plain Files] 0.15 Sound enabled '''BROKEN LINKS''' [http://www.dchomebrew.org/zacmcd/Files/oswandc.zip Plain Files] 0.1 [http://www.dchomebrew.org/zacmcd/Files/oswandc-NERO.zip Nero] 0.1 [http://www.dchomebrew.org/zacmcd/Files/oswandc-DJ.zip Discjuggler] 0.1 '''END BROKEN LINKS''' [https://files.dcemulation.org/software/dreamcast/emulators/oswandc/Oswandc.sbi Selfboot Inducer] 0.1, .015, Fullscreen 6ccd16350b3cc4856ede83de5e799d643bac29a1 2734 2723 2023-03-03T23:46:45Z Unknown user 0 wikitext text/x-wiki Developer: [http://www.fmf.nl/~timo/project/oswandc.html Timo Laman] Updated: 08-21-02 A port of Oswan a Bandai WonderSwan (& WonderSwan Color) emulator '''SCREENSHOTS HOSTED AT DCHOMEBREW''' Speed: 99% Sound: 10% [https://files.dcemulation.org/software/dreamcast/emulators/oswandc/oswandc-bin-0.15.zip Plain Files] 0.15 Sound enabled '''BROKEN LINKS''' [http://www.dchomebrew.org/zacmcd/Files/oswandc.zip Plain Files] 0.1 [http://www.dchomebrew.org/zacmcd/Files/oswandc-NERO.zip Nero] 0.1 [http://www.dchomebrew.org/zacmcd/Files/oswandc-DJ.zip Discjuggler] 0.1 '''END BROKEN LINKS''' [https://files.dcemulation.org/software/dreamcast/emulators/oswandc/Oswandc.sbi Selfboot Inducer] 0.1, .015, Fullscreen {{DCWiki:BrokenInternalLinks}} 84593d00870c3fe9589cf3f51cfe710b92a1e7f6 DCWiki:BrokenInternalLinks 4 1361 2724 2023-03-03T23:40:42Z Unknown user 0 Created page with "''This page contains broken links within DCEmulation/dreamcast.wiki's own domains. Fixing these links should be a high priority.''" wikitext text/x-wiki ''This page contains broken links within DCEmulation/dreamcast.wiki's own domains. Fixing these links should be a high priority.'' 5f394c03d0645acef6753a165d0ee9cf4ce4a6b5 NesterDC 0 808 2725 2662 2023-03-03T23:41:26Z Unknown user 0 /* Historical Files */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.tar.gz Source Code] 7.1 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.1-sdl.tar.gz Source Code] 7.1.1 (SDL) *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC7.1DJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7.1Nero.zip Nero] | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Historical Files== * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.zip Plain Files] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.tar.gz Source Code] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC.exe Best Damned Tutorial (Windows)] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-1ST_READ.BIN.zip 1ST_READ.BIN] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-PAL-1ST_READ.BIN.zip 1ST_READ.BIN] (PAL) * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0.tar.gz Source Code] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1-1ST_READ.BIN.zip 1ST_READ.BIN] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1.tar.gz Source Code] * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_src.zip Source Code] - 6/03/01 * 3.0t3 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-3.0t3.zip Plain Files] * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1.zip Plain Files] - 2/20/01 BROKEN * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.zip Plain Files] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 5.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-5.0.tar.gz Source Code] - 12/03/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 {{DCWiki:BrokenInternalLinks}} 946f4e41b957ee247501d7160d3566bd365be57f Genesis Plus DC 0 839 2726 2676 2023-03-03T23:42:04Z Unknown user 0 /* Compatibility */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Genesis Plus / DC| version=07/26/2006| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/Gpdc-gpwt-26072006-BA.zip GPDC BlackAura] 07/26/06 *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/gpdcq-012007.zip GPDC Quzar] 01/28/07 *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/genplus_dc_01_bin.zip GPDC v01] | release date=07/26/06| author=[[BlackAura]]| original=[http://cgfm2.emuviews.com/ GenesisPlus] by<br/>Charles MacDonald| systems=Sega Genesis| best=Yes.| isactive=Yes. }} Genesis Plus/DC is a port of Charles MacDonald's Sega Genesis/MegaDrive emulator, Genesis Plus, to the Dreamcast. It is currently the best available Sega Genesis emulator for the Dreamcast platform.It runs full speed on most games without frameskip with sound disabled. ==Features== * Full speed with full sound (no skipping!) * SRAM Saving to VMU * Great compatibility * 2 player support * 6 button pad support * Region settings (JP/US/EU) * .GEN, .BIN, .SMD, and .ZIP support * 2 CPU cores, FAME and C68K * Hardware and software rendering * Fixed graphic bugs from PVR3 version * Mono/Stereo settings (via Dreamcast BIOS) * Nice and easy to use GUI * GPDC is [[GPL|free software]] ===Missing Features=== * 4 player support * Frameskip options for the software renderer * Enhanced sound options ==History== GPDC started as a port of Genesis Plus by Charles Mac Donald. It's been in development since 2003 and a lot of progress has been made since then: BlackAura rewrote the video renderer for the Dreamcast's PowerVR2. Stef D of [http://gens.consolemul.com/ wGens] fame joined the project in 2004 to contribute fast and accurate CPU emulators: C68K & CZ80. Now with Fox68K's new SH4 Z80 emulator FAZE, and FAME, a 68K emulator written in Dreamcast's SH4 assembly language, and BlackAura working on sound emulation, the project has reached its final stage. An official release is expected for the end of this year. ===GPWT=== Until then there's the preview version of GenesisPlusDC Warmtoe & BlackAura released in 07/2006. It is called "GPWT" because it's been the first version to introduce a new GUI written by Warmtoe. ==Controls== ===Button Layout=== *Mega Drive A-Button: (X) *Mega Drive B-Button: (A) *Mega Drive C-Button: (B) *Mega Drive X-Button: (L) *Mega Drive Y-Button: (Y) *Mega Drive Z-Button: (R) *Mega Drive Start-Button: (Start) To exit a running game press (L) + (R) + (Start). ===In the Menu=== (Start) loads a game. Pressing + holding (Up)/(Down) scrolls through your game list. You can skip pages with (Left)/(Right) on the d-pad. To disable/enable 6 button support, press (X). To change the region settings, press (L). ===CPU Settings=== Some details about the different settings: Pressing (B) at the menu changes the CPU emulator. You can select either '''FAME''' - [http://www.m68k.com/fame/ Fox68k]'s great SH4 M68K emulator for fastest emulation, or '''C68K''' - [http://gens.consolemul.com/ Stef D]'s fast and accurate M68K emulator for better compatibility. ===Video Settings=== Press (A) to toggle the graphics renderer. You can select either '''HW''' - Hardware renderer written by BlackAura, using the Dreamcast's PowerVR II DC, very fast but inaccurate in a few games, or '''SW''' - Standard software renderer of GenesisPlusDC by Charles MacDonald, 100% accurate but much slower. ===Recommend Settings=== Recommend settings would be 'Render: HW' with 'CPU: FAME' - if this doesn't work for your game, try 'Render: HW' with 'CPU: C68K' (which is the default setting). ==ROMS.TXT== ===Method 1: Manual creation=== Make sure to rename the actual '.gen', '.bin', or '.zip' roms to not have spaces. ''Examples that'll work:'' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''Comix_Zone_(U)_[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone(U)[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone.bin'''' '''''The rest is straight from the readme:''''' In GPWT there is no directory browsing - just that fixed list of names for that fixed list of games. You put your (zipped) ROMS in the directory: \gpwt\data\ROMS It also expects to find a file: \gpwt\data\ROMS.txt In ROMS.TXT you can put the names of your games in there plus the name you'd like to see displayed on screen: SHINOBI.ZIP The Revenge of Shinobi 'SHINOBI.ZIP' (or 'shinobi.zip') would be your actual ROM, 'The Revenge of Shinobi' will be displayed on screen. Each file + name goes into a seperate line in ROMS.TXT. ===Method 2: Provlist by burnerO=== First download this: *Tool Set - [http://www.dcevolution.net/dsdevelopment/large/CE/gpwt-tools.zip Zipfile] Included are Provlist & Renamer which both are needed. 1. Copy your ROMs (*.zip) in /gpwt/data/ROMS/ and run Provlst.exe 2. Open ROMS.LST in Wordpad and replace ".SMC:" with ".ZIP " (space). 3. Save as 'ROMS.TXT' in /gpwt/data/ 4. Right-click on your /gpwt/data/ROMS/ folder and start Renamer 5. Click on 'Edit' -> 'Multi-Change' and replace "%a.SMC" with "%a.ZIP" 6. Click on 'A->B' to apply the changes and then close Renamer ===Method 3: Romlister by Smurph=== Download this application first: *Romlister - [http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Zipfile] 1. Zip all your roms. Keep them in a separate folder apart from the Plainfiles, or SBI, directories. 2. Start the rom lister. 3. Select the ''''data'''' subfolder from the the extracted Plainfiles, or SBI, packages. 4. Select your folder containing your zipped roms, and click on the 'Process' button. ==How To Burn== A little tutorial: ===Using Selfboot Inducer=== *1. At first you need to download [http://sbibuilder.dc-france.com/download/?idsys=2&idcat=15&idfile=115 Selfboot Inducer v4] and install it into C:/SBInducr/. *2. Then download a SBI for one of the GenesisPlusDC versions [http://www.dchelp.net/sbi HERE]. *3. Put this file into your C:/SBInducr/SBI/ folder. *4. Start C:/SBInducr/SBInducer.exe and check the SBI file showing up on the right window. Then select either "Single Menu" or "SBI2Boot" and click on 'Extract SBI'. *5. Browse to the C:/SBInducr/Inducer/gpwt/tools/ directory to find some tools. *6. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *7. Click on the 'CDRecord' button to burn the CD directly, or on the 'DiscJuggler' button to create a '.cdi' image. ===Using BootDreams=== *1. Download Bootdreams from http://dchelp.dcemulation.org, and install it. *2. Extract the plainfiles to their own folder. *3. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *4. Start Bootdreams. *5. Select the folder containing the plainfiles ''''''1st_read.bin''''''. *6. Choose your image type: '''''CDI''''', '''''NRG''''', or '''''MDF/MDS'''''. *7. Click on the process button. *8. Burn the image with your application of choice. To burn straight off Bootdreams, without creating an image, select the "CdRecord" option. To use the Bootdream's image burner select the "ImgRecord" option. ==Downloads== *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Smurph's GPWT RomLister v1.2] * Selfboot Inducer Versions: ''(To put both on one disc)'' **[http://dchelp.net/cgi-bin/sbi/browse/browse.cgi?browse&Emus Browse DCHelp's SBI File Repository] The files are called 'GenesisPlusDC-gpwt-260706-BlackAura.sbi', and 'GenesisPlusDC-gpwt-280107-Quzar.sbi'. ==Compatibility== Lists can be found here ''(W.I.P.)'': *[[GenesisPlusDC_BlackAura_list|GenesisPlusDC (BlackAura)]] http://dcemulation.org/1-newsdump/emulators/genesis/genesisplusdc/genplus_dc_01_src.tar.bz2 {{DCWiki:BrokenInternalLinks}} 52de04420b3a52dd74229789006177f27e542d61 PCSX WIP 0 870 2728 2024 2023-03-03T23:44:08Z Unknown user 0 wikitext text/x-wiki Developer: Ian Micheal Updated: 2003 A Playstation emulator that runs Ridge Racer at 10 frames per second Speed: 10 FPS Sound: [http://www.dcemulation.org/phpBB/viewtopic.php?t=36828 pcsx wip 1.5] [http://www.dcemulation.org/files/emulators/pcsx1.5wip.zip Plain Files] [http://www.dcemulation.org/files/sbi3.0/SBI-pcsx1.5wip.sbi Selfboot Inducer] =Other page= Developer: Ian Micheal Updated: 16-02-04 Better fullscreen mode, runs more games 2d games are playable but slow as before. But it is a bit smoother. About 10 fps [http://www.dcemulation.org/files/emulators/1_5wip4.rar Plain Files] {{DCWiki:BrokenInternalLinks}} 9ca8465f165d5e492eb9ba16e0f333412b7a3782 FunnyMu 0 876 2729 2031 2023-03-03T23:44:36Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | FunnyMu |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Funvision.jpg| Funvision]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://imrtechnology.ngemu.com/downloads/fun_binscr.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[Ian Micheal]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://www.lemoncube.com/26.html FunnyMu]}}} |- style="background:#ffffff" |Systems Emulated || {{{systems|Whizzard/<br/>Funvision/<br/>Creativision}}} |- style="background:#ffffff" |Best Available Emulator<br/>For this system(s)? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== This is a port of the SDL Funvision emulator FunnyMu to the Dreamcast. 'FunnyMu' is an emulator of the Whizzard, Funvision and Creativision computer/games consoles that were sold in the early 1980s. The VTech Creativision was distributed in Europe (Italy, Sweden and Germany for sure) and South Africa. However it was also marketed in other countries and called the "Dick Smith Wizzard", "FunVision Computer Video Games System" and "Hanimex Rameses". The Wizzard may have been a licensed version for the Australian market since Dick Smith Industries maintained the VTech logo, but the others most likely were clones. The FunVision had a slight alteration that made the carts and cartridge slot larger. ==Downloads== * FunnyMu - [http://imrtechnology.ngemu.com/downloads/fun_binscr.rar Plainfiles], [http://dreamcast.dcemu.co.uk/fun_binscr.rar Alt.] - ''Unknown release date * FunnyMu - [http://imrtechnology.ngemu.com/downloads/funvision_cdi.rar CDI Image] - ''Unknown release date * FunnyMu - [http://imrtechnology.ngemu.com/downloads/fun_src.rar Source] - ''Unknown release date {{DCWiki:BrokenInternalLinks}} 2303a43b63a8518724608e94ec567d12c84692f4 SIemu 0 941 2732 2106 2023-03-03T23:45:54Z Unknown user 0 wikitext text/x-wiki Developer: Ian Micheal Updated: 2003 An emulator that runs the classic 1970's arcade game, Space Invaders. Speed: 100% Sound: ??? [http://www.dcemulation.org/files/emulators/siemu.zip Plain Files] [http://www.dcemulation.org/files/sbi3.0/SBI-SIemu.sbi Selfboot Inducer] {{DCWiki:BrokenInternalLinks}} 36fe5afbd8ec06999bd4289b74694a298e7446cb Visual Troy Advance 0 913 2735 2074 2023-03-03T23:49:01Z Unknown user 0 wikitext text/x-wiki == Visual Troy Advance == {{Infobox_Emulator_Information| name=Visual Troy Advance| image=[[File:vta.png|center|250px]]| homepage=[http://gpf.dcemu.co.uk/visualtroyadvance.shtml Homepage]| version=1.4| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/visualtroyadvance/VTA1.4.rar Binary (Plain Files)]<br/>[https://files.dcemulation.org/software/dreamcast/emulators/visualtroyadvance/VisualBoyAdvance1.80DCSrc.rar Source Code]<br/>| release date=06/03/2005| author=GPF (Troy Davis)<br/>| original=VBA-Team<br/>(Visual Boy Advance)| systems=GBA/GB/GBC| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Visual Troy Advance is a port of Visual Boy Advance 1.80 by GPF. Visual Troy Advance runs very slow. == Controls == *X = B *A = A *L Trigger = L *R Trigger = R *Start = Start *Y = Select f0b4cd5289269615ad44d31ebfc0a2937647bb91 2736 2735 2023-03-03T23:49:13Z Unknown user 0 /* Visual Troy Advance */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Visual Troy Advance| image=[[File:vta.png|center|250px]]| homepage=[http://gpf.dcemu.co.uk/visualtroyadvance.shtml Homepage]| version=1.4| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/visualtroyadvance/VTA1.4.rar Binary (Plain Files)]<br/>[https://files.dcemulation.org/software/dreamcast/emulators/visualtroyadvance/VisualBoyAdvance1.80DCSrc.rar Source Code]<br/>| release date=06/03/2005| author=GPF (Troy Davis)<br/>| original=VBA-Team<br/>(Visual Boy Advance)| systems=GBA/GB/GBC| best=Yes.| refreshrate=50Hz / 60Hz| isactive=No }} Visual Troy Advance is a port of Visual Boy Advance 1.80 by GPF. Visual Troy Advance runs very slow. == Controls == *X = B *A = A *L Trigger = L *R Trigger = R *Start = Start *Y = Select d7187cecef333cc41fd6cfce0e8cfdf37c8b4e30 Boob!boy 0 927 2737 2092 2023-03-03T23:56:30Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Boob!boy| image=[[Image:boobboy.jpg|center|thumb|250px| Boob!boy]]| homepage=[http://www.boob.co.uk/emulators/gameboy.html Homepage]| version=1.5| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/boobboy/boobboy.zip Plain Files]| release date=12/22/2000| author=[[CyRUS64]]| original=Boob!boy| systems=Nintendo GameBoy<br />GameBoy Color| best=No| refreshrate=60Hz| isactive=No }} ==History== Boob!boy is the first Gameboy emulator for the Dreamcast by [[CyRUS64]]. Its name is inspired by the Dreamcast website B00B! Dreamcast Research, since the author, [[CyRUS64]], was the founder of B00B!. Unlike most other emulators, Boob!boy was written from scratch and is not a normal port. There also exists a PC version of Boob!boy which supports sound. ''Screenshots:<br/>[http://www.dcemulation.org/images/screens/boob_boy01.jpg Image 1], [http://www.dcemulation.org/images/screens/boob_boy02.jpg Image 2], [http://www.dcemulation.org/images/screens/boob_boy03.jpg Image 3],<br/>[http://www.dcemulation.org/images/screens/boob_boy04.jpg Image 4], [http://www.dcemulation.org/images/screens/boob_boy05.jpg Image 5], [http://www.dcemulation.org/images/screens/boob_boy06.jpg Image 6]. ===Feaures=== * Frameskip implemented - Boob!boy should now be faster with only a small amount of frameskipping noticeable. For example, Super Mario Land without doubt now runs at FULL SPEED. * Super Gameboy Support added * Fixed a memory problem that meant memory wasn't being freed up after the game was exited and hence when you had played 4/5 games the dc would run out of memory and crash. You should now be able to play as many different games as you want without having to reset the dc! * Swapped around A and B keys to make it more like a real gameboy! * New menus - a license screen is now displayed explaining that Boob!boy is not licensed or endorsed by Sega. Also a menu screen has been implemented which currently only features a play game option... (pretty pointless at the moment then!) * Made game-select screen more user-friendly by speeding up page-select and game-select movements * Fixed bug causing a delay before loading the game to be played * Implemented load from file functions saving much-needed memory... This also has resulted in a speed-up in the emulation since Video Ram can now be used for more important tasks! * Found and "zapped" other little bugs in the code, which although didn't cause any problems in current versions would have done so in the future. ===Bugs=== * Since sound caused Boob!boy to crash on the Dreamcast, it has been disabled in the Dreamcast version. ==Downloads== * 1.5 (KOS) - [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/boobboy.zip Plain Files] * 1.5 (KOS)- [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boobboy_1.5_bO.sbi SBI] * 1.5 (KOS)- [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boobboy.sbi SBI (alt?)] * 1.5 beta (WINCE) - [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boob!boy.zip Plain Files] b36da5cc0dd0506083fb65bcc230d4d41bdf2f2d 2738 2737 2023-03-03T23:56:54Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Boob!boy| image=[[Image:boobboy.jpg|center|thumb|250px| Boob!boy]]| homepage=[http://www.boob.co.uk/emulators/gameboy.html Homepage]| version=1.5| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/boobboy/boobboy.zip Plain Files]| release date=12/22/2000| author=[[CyRUS64]]| original=Boob!boy| systems=Nintendo GameBoy<br />GameBoy Color| best=No| refreshrate=60Hz| isactive=No }} ==History== Boob!boy is the first Gameboy emulator for the Dreamcast by [[CyRUS64]]. Its name is inspired by the Dreamcast website B00B! Dreamcast Research, since the author, [[CyRUS64]], was the founder of B00B!. Unlike most other emulators, Boob!boy was written from scratch and is not a normal port. There also exists a PC version of Boob!boy which supports sound. ''Screenshots:<br/>[http://www.dcemulation.org/images/screens/boob_boy01.jpg Image 1], [http://www.dcemulation.org/images/screens/boob_boy02.jpg Image 2], [http://www.dcemulation.org/images/screens/boob_boy03.jpg Image 3],<br/>[http://www.dcemulation.org/images/screens/boob_boy04.jpg Image 4], [http://www.dcemulation.org/images/screens/boob_boy05.jpg Image 5], [http://www.dcemulation.org/images/screens/boob_boy06.jpg Image 6]. ===Feaures=== * Frameskip implemented - Boob!boy should now be faster with only a small amount of frameskipping noticeable. For example, Super Mario Land without doubt now runs at FULL SPEED. * Super Gameboy Support added * Fixed a memory problem that meant memory wasn't being freed up after the game was exited and hence when you had played 4/5 games the dc would run out of memory and crash. You should now be able to play as many different games as you want without having to reset the dc! * Swapped around A and B keys to make it more like a real gameboy! * New menus - a license screen is now displayed explaining that Boob!boy is not licensed or endorsed by Sega. Also a menu screen has been implemented which currently only features a play game option... (pretty pointless at the moment then!) * Made game-select screen more user-friendly by speeding up page-select and game-select movements * Fixed bug causing a delay before loading the game to be played * Implemented load from file functions saving much-needed memory... This also has resulted in a speed-up in the emulation since Video Ram can now be used for more important tasks! * Found and "zapped" other little bugs in the code, which although didn't cause any problems in current versions would have done so in the future. ===Bugs=== * Since sound caused Boob!boy to crash on the Dreamcast, it has been disabled in the Dreamcast version. ==Downloads== * 1.5 (KOS) - [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/boobboy.zip Plain Files] * 1.5 (KOS)- [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boobboy_1.5_bO.sbi SBI] * 1.5 (KOS)- [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boobboy.sbi SBI (alt?)] * 1.5 beta (WINCE) - [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boob!boy.zip Plain Files], [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boob!boy.txt Readme] ffe3bddb73355008387a470c90e5a3f26afa5279 Emulators on Dreamcast 0 108 2741 2242 2023-03-04T00:08:09Z Unknown user 0 /* Single-game Emulators */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[Phoenix]] *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[SarienDC]] *[[ScummVM]] (Lucas Arts Adventures) 47f2e64e24b71068cd12f17686303dd1329de02c 2748 2741 2023-03-04T00:28:56Z Unknown user 0 /* Sega Dreamcast VMU */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[Phoenix]] *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS for DC]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[Heart of the Alien|HOTA]] (Heart of the Alien) *[[MilkDC]] *[[onscripter]] *[[RAW]] (Another World) *[[REminiscence]] (Flashback) *[[SarienDC]] *[[ScummVM]] (Lucas Arts Adventures) 47582bcc832aef671fba256fe4cea1870c34c034 Gnuboy/DC 0 928 2743 2093 2023-03-04T00:19:31Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=gnuboy/DC| image=[[Image:Gnuboydc.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/?gnuboy%2FDC Current]<br/>/[http://pqrs.org/dreamcast/software/dcgnuboy/ Old]| version=1.0.4| downloads=[http://dchelp.dcemulation.org/?download=gnuboydc_104.zip Plain Files]<br/>[http://dchelp.dcemulation.org/?download=gnuboydc_104_src.zip Source]| release date=04/06/2008| author=emptythought ''(1.0.4 ↑)''<br/>[[Takayama Fumihiko]] ''(1.0.3 ↓)''| original=[http://brightrain.aerifal.cx/~laguna/ Gnuboy]| systems=Nintendo Gameboy/<br/>Gameboy Color| refreshrate=60Hz| firstversion=''Unknown| best=Yes| isactive=Yes| }} ==History== A great port of the Gameboy Color emulator gnuboy by [[Takayama Fumihiko]], which he left at version '1.0.3-0.6'. It later received some minor updates by Fackue, with help from [[Quzar]]. It now has support for zipped roms (.zip), and slightly higher game compatibility. ===Features=== * GB/GBC emulate with sound. * smooth sound with GBC. * save support (with long filename support) * state save/load * frameskip. * screen adjustment. * added support for Zipped roms * save icon for VMU saves ===Bugs=== * ROM path display ==Downloads== * 1.0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104.zip Plain Files] - 04/06/2008 * 1.0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104_src.zip Source] - 04/06/2008 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/gnuboy-1.0.3-0.6.zip Plain Files] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/Gnuboy_1.0.3_bO.sbi SBI] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/Gnuboy.sbi SBI (alt)] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboyNero.zip Nero] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboyDJ.zip DiscJuggler] - 08/04/2002 * 1.0.3 - [ftp://ftp.pqrs.org/dc/gnuboy/source/dcgnuboy-1.0.3-0.6.tar.gz Source] - 08/04/2002 {{DCWiki:BrokenInternalLinks}} ==Links== * [http://www.dcevolution.net/index.php?id=gameboy_gameboy_color DCEvolution]: Dream Emulation Project * [http://sourceforge.net/projects/gnuboydc/ Sourceforge]: Hosted Page 00214e0e3e3e9e82c87baf62bd7157b035080c5e 2744 2743 2023-03-04T00:20:01Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=gnuboy/DC| image=[[Image:Gnuboydc.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/?gnuboy%2FDC Current]<br/>/[http://pqrs.org/dreamcast/software/dcgnuboy/ Old]| version=1.0.4| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104.zip Plain Files]<br/>[https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104_src.zip Source]| release date=04/06/2008| author=emptythought ''(1.0.4 ↑)''<br/>[[Takayama Fumihiko]] ''(1.0.3 ↓)''| original=[http://brightrain.aerifal.cx/~laguna/ Gnuboy]| systems=Nintendo Gameboy/<br/>Gameboy Color| refreshrate=60Hz| firstversion=''Unknown| best=Yes| isactive=Yes| }} ==History== A great port of the Gameboy Color emulator gnuboy by [[Takayama Fumihiko]], which he left at version '1.0.3-0.6'. It later received some minor updates by Fackue, with help from [[Quzar]]. It now has support for zipped roms (.zip), and slightly higher game compatibility. ===Features=== * GB/GBC emulate with sound. * smooth sound with GBC. * save support (with long filename support) * state save/load * frameskip. * screen adjustment. * added support for Zipped roms * save icon for VMU saves ===Bugs=== * ROM path display ==Downloads== * 1.0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104.zip Plain Files] - 04/06/2008 * 1.0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104_src.zip Source] - 04/06/2008 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/gnuboy-1.0.3-0.6.zip Plain Files] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/Gnuboy_1.0.3_bO.sbi SBI] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/Gnuboy.sbi SBI (alt)] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboyNero.zip Nero] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboyDJ.zip DiscJuggler] - 08/04/2002 * 1.0.3 - [ftp://ftp.pqrs.org/dc/gnuboy/source/dcgnuboy-1.0.3-0.6.tar.gz Source] - 08/04/2002 {{DCWiki:BrokenInternalLinks}} ==Links== * [http://www.dcevolution.net/index.php?id=gameboy_gameboy_color DCEvolution]: Dream Emulation Project * [http://sourceforge.net/projects/gnuboydc/ Sourceforge]: Hosted Page ccae8181a0e02457f6db57a3f8b984da7b0ceea0 PokeMini Dream 0 908 2745 2068 2023-03-04T00:22:39Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=PokeMini Dream| image=[[File:PokeMiniDream.jpg|center|256px|Game Screen]]| homepage=[http://pokeme.shizzle.it/ Homepage]| version=2.0| downloads=Plain Files:<br>[http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2.zip NTSC 2.0]<br>[http://dcemulation.org/1-newsdump/emulators/PokeMiniDreams/PokeMiniDream2PAL.zip PAL 2.0]| release date=9/11/04| author=[[JustBurn]]| original=[http://pokeme.shizzle.it/ PokeMini] by<br/>JustBurn| systems=Pokémon mini| best=Only| refreshrate=50Hz/60Hz| isactive=No }} PokeMini Dream is a Dreamcast port by [[JustBurn]] of his Pokemon mini emulator for Windows. It has no sound/rumble support. Only a handful of public domain roms I tried worked, but the PD roms/demos that I tested can be found below. A variety of demos, PD roms (including what I tested), and the Win32 version emulator can be found download at the host site [http://pokeme.shizzle.it/ Team Pokémé]. Check under the "Files" section. =Controls= File List: *Button A = Select File *Button B = Go Parent Directory *DPAD Left = Move Prev. Page *DPAD Right = Move Next Page *DPAD Up = Cursor Up *DPAD Down = Cursor Down In-Game: *Button A = Button A of Pokemon Mini *Button B = Button B of Pokemon Mini *Button Y = Button C of Pokemon Mini *Button X = Not Used yet (For Shock Detector) *DPAD Left = DPAD Left of Pokemon Mini *DPAD Right = DPAD Right of Pokemon Mini *DPAD Up = DPAD Up of Pokemon Mini *DPAD Down = DPAD Down of Pokemon Mini *Joystick X/Y = Same as DPAD *Start = Power Button of Pokemon Mini *L+R Triggers (Less that 2 secs pressed) = Reset ROM *L+R Triggers (More that 2 secs pressed) = Go to Filelist =Downloads= *Version 2 NTSC - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream2.zip Plain Files (Unscrambled)] - 09/11/04 *Version 2 PAL - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream2PAL.zip Plain Files (Unscrambled)] - 09/11/04 *Version 1 NTSC - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream1.zip Plain Files (Unscrambled)] - 08/26/04 *Version 1 PAL - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream1PAL.zip Plain Files (Unscrambled)] - 08/26/04 *Public Domain (PD) ROMs - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PDroms.zip Zipfile] a0cfb231910579c3e403f7f49bc6dafd37b5defd 2746 2745 2023-03-04T00:22:56Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=PokeMini Dream| image=[[File:PokeMiniDream.jpg|center|256px|Game Screen]]| homepage=[http://pokeme.shizzle.it/ Homepage]| version=2.0| downloads=Plain Files:<br>[https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream2.zip NTSC 2.0]<br>[https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream1PAL.zip PAL 2.0]| release date=9/11/04| author=[[JustBurn]]| original=[http://pokeme.shizzle.it/ PokeMini] by<br/>JustBurn| systems=Pokémon mini| best=Only| refreshrate=50Hz/60Hz| isactive=No }} PokeMini Dream is a Dreamcast port by [[JustBurn]] of his Pokemon mini emulator for Windows. It has no sound/rumble support. Only a handful of public domain roms I tried worked, but the PD roms/demos that I tested can be found below. A variety of demos, PD roms (including what I tested), and the Win32 version emulator can be found download at the host site [http://pokeme.shizzle.it/ Team Pokémé]. Check under the "Files" section. =Controls= File List: *Button A = Select File *Button B = Go Parent Directory *DPAD Left = Move Prev. Page *DPAD Right = Move Next Page *DPAD Up = Cursor Up *DPAD Down = Cursor Down In-Game: *Button A = Button A of Pokemon Mini *Button B = Button B of Pokemon Mini *Button Y = Button C of Pokemon Mini *Button X = Not Used yet (For Shock Detector) *DPAD Left = DPAD Left of Pokemon Mini *DPAD Right = DPAD Right of Pokemon Mini *DPAD Up = DPAD Up of Pokemon Mini *DPAD Down = DPAD Down of Pokemon Mini *Joystick X/Y = Same as DPAD *Start = Power Button of Pokemon Mini *L+R Triggers (Less that 2 secs pressed) = Reset ROM *L+R Triggers (More that 2 secs pressed) = Go to Filelist =Downloads= *Version 2 NTSC - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream2.zip Plain Files (Unscrambled)] - 09/11/04 *Version 2 PAL - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream2PAL.zip Plain Files (Unscrambled)] - 09/11/04 *Version 1 NTSC - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream1.zip Plain Files (Unscrambled)] - 08/26/04 *Version 1 PAL - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PokeMiniDream1PAL.zip Plain Files (Unscrambled)] - 08/26/04 *Public Domain (PD) ROMs - [https://files.dcemulation.org/software/dreamcast/emulators/pokeminidreams/PDroms.zip Zipfile] ded8f8f6f7f2167a73e91674c71158cdbf270e15 VMoo 0 919 2747 2081 2023-03-04T00:28:04Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=VMoo| image=N/A| homepage=[http://bullandfish.net Homepage]| version=Alpha 1| downloads=See List<br/>| release date=Unknown| author=Dirty Sanchez| original=Marcus Comstedt<br/>(VMU Emulator)| systems=DreamCast VMU| best=No| isactive=No }} Developer: Dirty Sanchez<br/> Updated: 08-02-04<br/> Description: <br/> VMoo Mad Cow/Chao Edition Alpha 1 is a port of Marcus Comstedt's VMU emulator to run on the Dreamcast. The speed is about 90-95% correct. =Downloads= * Alpha 1 - [https://files.dcemulation.org/software/dreamcast/emulators/vmoo/vmoo.elf.gz Plain Files] Elf [[category:Emulator]] 5f1f607903a3938ad2ed0444885c30cca5e1b0b8 SoftVMS for DC 0 1362 2749 2023-03-04T00:32:10Z Unknown user 0 Created page with "Written by Marcus Comstedt, SoftVMS for DC is an emulator capable of running some VMS games. *[https://files.dcemulation.org/software/dreamcast/emulators/softvmsdc/softvms_dc..." wikitext text/x-wiki Written by Marcus Comstedt, SoftVMS for DC is an emulator capable of running some VMS games. *[https://files.dcemulation.org/software/dreamcast/emulators/softvmsdc/softvms_dc.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/softvmsdc/softvms.tar.gz Source Code] c7d1315b045af8331224aa7ea15141c85ca3fb80 Dream Explorer 0 1363 2750 2023-03-04T00:33:03Z Unknown user 0 Created page with "See [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on BlueSwirl]" wikitext text/x-wiki See [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on BlueSwirl] 5a3f963a9fa69d4c44796fe6e3cedfa4f93db5be NeoPocott DC 0 922 2751 2084 2023-03-04T00:36:53Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=NeoPocott DC| image=No Screenshot Available| homepage=[http://www.ganksoft.com Homepage]| version=V1.0| downloads=See List<br/>| release date=04/25/04| author=Ganksoft| original=Julien Frelat<br/>(NeoPocott DC)| systems=NeoGeo Pocket| best=Unknown| isactive=Unknown }} Updated: 12-26-00 <br/> Description: A Neo Geo Pocket Color emulator for the Sega Dreamcast. It is a port of Julien Frelat's emulator of the same name. Speed: 75% <br/> Sound: None =Downloads= * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/neopocottdc/npdc10if.zip Plain Files] 431kb * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/neopocottdc/npdc10dj.zip Discjuggler] 1.27mb * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/neopocottdc/npdc10ne.zip Nero] 982kb * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/neopocottdc/Neopocott.sbi Selfboot Inducer] (Sbi v2.1) 401kb * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/neopocottdc/Neopocott3.0.sbi Selfboot Inducer] (Sbi v3.0) [[Category:Emulator]] 044057c269eb5fe4f3b6abb46d39672ea9e4a3d3 NeoCD/SDL DC 0 865 2752 2695 2023-03-04T00:37:47Z Unknown user 0 wikitext text/x-wiki Developer: Ian Micheal Updated: 18-05-04 A very cool port of the Neo Geo CD emulator NEOCD/SDL [http://dcemulation.org/phpBB/viewtopic.php?p=518878#518878 NeoGeoCD/SDL V7 Game Testing Topic] Dreamcast Port Credits: [[Ian Micheal]], [[Fosters]], Troy "[[GPF]]" Davis, [[BlackAura]], [[BlueCrab]] CREDITS -------------------------------- Fabrice Martinez - The original NeoCD emulator Fosters - SDL port Caz - For the BeOS NeoCD/SDL build Karl Stenerud - The Musashi M680x0 emulator Neil Bradley (neil@synthcom.com) - Multi-Z80 CPU emulator Tatsuyuki Satoh - YM2610 Mame core Derek Liauw Kie Fa. - 2xSaI engine Sam Lantinga (et al) - Simple DirectMedia Layer Quzar- Region selector, frameskip, frame limiting, auto loading, many bugfixes and optimizations. Mekanizer - proper vmu display *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7bin.rar v7 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7.rar v7 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6bin.rar v6 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6src.rar v6 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/NGCDv5_5.rar v5.5 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/sourcev5_5.rar v5.5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5bin.rar v5 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5_source.rar v5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v4.rar v4 Plain Files] 224d1fee7d5fa869a705bb2d62c906103dd0b1c7 2753 2752 2023-03-04T00:38:55Z Unknown user 0 wikitext text/x-wiki Developer: Ian Micheal Updated: 18-05-04 A very cool port of the Neo Geo CD emulator NEOCD/SDL [http://dcemulation.org/phpBB/viewtopic.php?p=518878#518878 NeoGeoCD/SDL V7 Game Testing Topic] Dreamcast Port Credits: [[Ian Micheal]], [[Fosters]], Troy "[[GPF]]" Davis, [[BlackAura]], [[BlueCrab]] CREDITS -------------------------------- Fabrice Martinez - The original NeoCD emulator Fosters - SDL port Caz - For the BeOS NeoCD/SDL build Karl Stenerud - The Musashi M680x0 emulator Neil Bradley (neil@synthcom.com) - Multi-Z80 CPU emulator Tatsuyuki Satoh - YM2610 Mame core Derek Liauw Kie Fa. - 2xSaI engine Sam Lantinga (et al) - Simple DirectMedia Layer Quzar- Region selector, frameskip, frame limiting, auto loading, many bugfixes and optimizations. Mekanizer - proper vmu display *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7bin.rar v7 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/V7.rar v7 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6bin.rar v6 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v6src.rar v6 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/NGCDv5_5.rar v5.5 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/sourcev5_5.rar v5.5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5bin.rar v5 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v5_source.rar v5 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/neocdv4bin.rar v4 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/neocdsdldc/v4.rar v4 Source] 641af2ca14bc549779b54c50c31d21dfd9ee0c15 Apple II Soul Captor 0 915 2754 2076 2023-03-04T00:57:15Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Apple II Soul Captor| image=No Image Available| homepage=Unknown| version=August, 2002| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/apple2soulecaptor/a2sc-bin-1.zip Plain Files] | release date=Unknown| author=[http://consolevision.com/members/dcgrendel/ DCGrendel]| original=N/A| systems=Apple II / II+| best=Unknown| isactive=No }} Developer: [http://consolevision.com/members/dcgrendel/ DCGrendel] <br> Updated: August, 2002 <br> <br> Emulation of the Apple II and II+ computers, with support for save states, disk images (read only), multilingual menu support (English menus distributed, third parties are welcome to translate the menu files into their home language.) <BR><BR> Speed: 100% Sound: 50% ==Downloads== [https://files.dcemulation.org/software/dreamcast/emulators/apple2soulecaptor/a2sc-bin-1.zip Plain Files] 5899fcb2dd9dcb2d054902c874aa10b66e08a65b (D)Colem 0 791 2755 2645 2023-03-04T00:58:59Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=[D]Colem| image=[[File:Dcolem4.jpg|center|250px]]| homepage=[http://dcolem.emuunlim.com/ Homepage]| version=0.99| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/d99sb.zip DiscJuggler] 0.99 *[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/d99p.zip Plain Files] 0.99 *[https://files.dcemulation.org/software/dreamcast/emulators/dcolem/dcolem09plain.zip Plain Files] 0.9 | release date=06/18/01| author=Marc Dietrichstein<br/>([[Gonzo]])| original=[http://fms.komkon.org/ColEm/ ColEm]<br/>by Marat Fayzullin| systems=ColecoVision| firstversion=[http://www.dcemulation.com/files/emulators/dcolem/dcolemwhatever.zip FIXME]<br/>| best=Yes| isactive=No| refreshrate=50Hz }} [D]Colem is the only ColecoVision emulator on the Sega Dreamcast. It is based on [http://fms.komkon.org/ColEm/ ColEm] was ported to Dreamcast by Austrian Dreamcast developer [[Gonzo]]. [D]Colem is reported to run fullscreen with sound. =Known bugs= *8 and 9 keys aren't properly emulated *Video flickering on 60Hz displays [[Category:Emulator]] 580ac2410cb779d7ac21c60fcad2d7e6c73ae3f6 Sintendo 0 836 2756 1985 2023-03-04T01:04:40Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Sintendo| image=[[File:sintendo.jpg|center|250px]]| homepage=[http://sintendo.dcemulation.org/ Homepage]| version=0.10-pre2| downloads=[http://sintendo.dcemulation.org/files/BetaTest010-2.zip Plain Files]<br/>[http://sintendo.dcemulation.org/files/Sintendo-Source-August-18-2001.zip Source code]| release date=08/03/2001| author=Jamin Vander Berg (aka [[Sin]])| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} Sintendo was one of the earliest emulators for the Dreamcast console. It it a port of Snes9x by Jamin Vander Berg (aka [[Sin]]). It was made using the [[WinCE]] SDK. The newest version is Sintendo Beta v0.10 - Prerelease version 2 which was released on August 3, 2001. The Sintendo website is hosted by DCEmulation.com. Sintendo doesn't support sound or saving games. [[Sin]] planned to include both in a future version of Sintendo but he never released it. Here's some status information by [[Sin]]: *Memory allocation is working. *Port to dreamcast successfull. Little slow at the moment. *Features done are MOD emulation, Joystick Support and saving. *Little bit of sound and graphics done. Old versions of Sintendo can be downloaded from [http://sintendo.dcemulation.org/ the official site]. The official forums are still up, but hadn't had any activity since years. They can be found [http://pub21.ezboard.com/bdcsnes here] but all previous posts have gone lost. == Activity == Below is a post from [[Sin]] that he made on 27th December 2002. It is one of last posts he made in his own forum. His last post there was on 22th January 2003 responding to someone who had replied to this message. He has never been active again in any Dreamcast forum. The original topic can be found [http://web.petabox.bibalex.org/web/20041217131810/p210.ezboard.com/fdcsnesdcsnes.showMessage?topicID=99.topic here]. ''It has been a great deal of time since I have updated this website, reviewed the posts here, or even touched the code for Sintendo.'' ''In recent ponderings, I have wondered if what I have done is worth working further forward towards. While I am deeply satisfied with how far everything has come (some may not agree, but I doubt they are programmers), I still never got it as far as I had hoped.'' ''The Dreamcast is all but a dead system. Many of us still use ours, I pop a disc in and play from time to time, but all of the effort I've put into Sintendo in the past, while not wasted, may fall on deaf ears if I continue to pursue the project, so long after the consoles unfortunate demise.'' ''Work, as always, is a burden on a creative programmer's time and imagination. I'll not use that as an excuse for anything. I still program from time to time, but its been quite a while since I've approached anything that compares with the scope of Sintendo.'' ''Never before or since have I conceived a project with such determination to see it through to even as close a level of completion. Anyone who programs (and some who don't) should understand the year plus of plight that went into this project. I appreciate all of the support I have received over this time. I gratefully appreciate my host, dcemulation.com, for keeping this site up more than a year after a single update.'' ''I am by no means saying that Sintendo is a dead project. I am not quitting, per se. I am only trying to tell all of you, what few dedicated followers I may have left, that I have not worked on it for quite some time, and can't necessarily forsee any time in the future when I will. I can not even promise that Sintendo *will* ever be worked on (by me at least), but I'd like to think that that's not the case.'' ''I have been dedicated to games programming since the age of 15. Now, 25, I still work towards the same goal. Sintendo bore me priceless experience in the console programming market that I will take with me in the future. Where it will lead? I can't say for certain. I'd like to develop games for many years to come. Personally, and most importantly, I'd like to develop a game to completion. Perhaps we may some day see Sintendo on another console (although I currently own none to port it to). Time will tell.'' ''Thank you all again for all the support I've received. I apologize for lack of adequete postings as well as lack of decisiveness.'' ''Until another time,'' ''Sin'' ==Downloads== https://files.dcemulation.org/software/dreamcast/emulators/sintendo/BetaTest010-2.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/BetaTest010.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Build34.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-April-19-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-April-24-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-August-18-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-May-1-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/s9xs132.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendo-source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendo56.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta001source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta002.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobuild209.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobuild209source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sourcesnes9xwin.exe ==Interview== This is an interview with [[Sin]], the creator of Sintendo. It was taken in late 2001 by Emulation-X of GeoShock, a popular emulation site in these days. GeoShock went offline in early 2006, so we have published this interview here. '''Emulation-X: Why did you make Sintendo?''' Sin: I made Sintendo because I wanted to be able to play Super Nintendo games on my Dreamcast. I released Sintendo to the world because I imagined other people would like to as well. There was once a time when such a thing was only imaginable and I saw that I *could* do it... I used Snes9x because it is portable, maybe the development a lot easier The only other really useful SNES emulator is ZSNES, which may be better in some ways, but is far from portable. ZSNES is written primarily in x86 assembly, everything written in that way must be re-written to work on the Dreamcast. Snes9x was just a much more attractive option because it's written in C.I have had to do very little re-writing of the Snes9x code. I started most of my research on the forums of the "warez" sites. Dcisos.com had a development forum The portable version of Snes9x has a file called how2port.txt. Its like following instructions, kind of It's quite a bit more complicated than that. '''Emulation-X: Who made the a big Impact with you while making Sintendo?''' Sin: I'd have to say Gary, the author of Snes9x had a huge impact on me.The fact that he responded to my email suprised me, and while he hasn't given me any particular help... He has been very supportive...as well as creating the thing in the first place. Tubooboo has helped me solve a few of my most frustrating problems. Tubooboo's presence on the scene was also a great motivating force i wish a great deal of success to him with his project. '''Emulation-X: Tubooboo also has a Snes Emulator for the Dreamcast. Was this a race?''' Sin: The fact that he started it, however, spurred a great deal of competitiveness in me that was probably the direct cause of Sintendo being released on time there was probably an unspoken race between us. the race ended when Marcus won, by a half a day I released my emulator later that day, and then an improved version the next. It has sound and saving, two great feats,but I understand that the sound slows down the emulation somewhat and speed in controlled by a frameskip, which takes away some of the smoothness from the games. '''EMULATION-X: When did you get involved in Emulation?''' Sin: I don't know when really maybe around Nesticle.It ran on our P100 at good speed, it was fun to play all those old games even my mom loved it. Then emulators started coming out that emulated the SNES following in a loose sense of the term. I've used a lot of them,I've even considered doing SNES emulation myself. I had a few ideas but never the time to research all the ins and outs the SNES is a very complicated machine.I used to imagine that compiling a SNES cartridge into machine code would speed emulation a great deal...and it probably would...it is unfortunately not very practical . '''EMULATION-X: Besides making Sintendo (Snes for DC) are there any other Emulators that you might want to port in the future to the Dreamcast?''' Sin: I don't have any intention on porting another emulator to the DC.Though SNES emulation on the PS2 would be very cool...and certainly be less problematic that my orignal port I haven't exactly decided yet. I am a games programmer at heart. I love RPGs in specific and I can't play one without analysing it a great deal I've been programming rudementary RPGs since I first started programming and it is perhaps the reason I began programming in the first place. So I guess there's a good chance that may be my next route '''Emulation-X: What other Emus do you use besides Snes9x?''' Sin: I kind of like Pokemon, so sometimes I use the no$gb emulator, or whatever on the PC version you can run more than one gameboy...which makes trading useful, and I programmed a small app that switches the save files arround so I can play more than one save... and if I click one check box, I can trade without actually losing the pokemon I traded (i.e. Copy a Pokemon) '''EMULATION-X: What is your View on Utopia boot disk (DC-warez) and the hole shut down of the DC news web sites?''' Sin: The boot disk is a good thing, and I don't believe it is really illegal. News sites are news sites, and Sega has no right toshut them down for providing information regardless of the nature of that information '''EMULATION-X: Has Sega or Nintendo never tried to contact you ?''' Sin: No, but I have considered contacting them. Perhaps obtain a license for Sintendo... or get a job :) or licensing for future projects like the aforementioned RPG its an option i am looking into I'd imagine the people that use it for emulation will be using it for some time to come '''Emulation-X: What do you think about the Dreamcast Now?''' Sin: As a consumer system, it's closed to dead. No one really wants to spend any money on it any more the games have been released (illegally) for free. '''EMULATION-X: Do you think that Emulation and Warez kills a system?''' Sin: Yes and no. Warez killed a lot of profits Sega and its developers could have made. But then all those kids bought tons of accessories because they had extra money. Emulation is a program I don't think in and of itself emulation and emulators for the Dreamcast could kill the system But then, it's kindof like cheating at a game... You played it for a while and you're bored... so you want something new... So you cheat to make it more exciting... eventually (maybe sooner, maybe later) thats gets old too... but the game was already old in the first place if you catch my analogy, but I know I'll stick pick up my Dreamcast for years to come and play some old SNES games . '''EMULATION-X: Where did the name Sintendo come from?''' Sin: spankthemonkey, my web designer, thought of it. '''EMULATION-X: Do you plan on improving on Sintendo anytime soon?''' Sin: I'm still improving Sintendo almost every day there's a lot that still has to be done speed is an issue, no one wants to play a game (at least not for a great deal of time) if it's slow, saving should be implemented soon and I really want to be able to hear the music for ChronoTrigger while I'm playing. There are a few details that were left out from my first release I am covering those bases (and maybe throwing in a few extras) and I'll release in under a week. '''EMULATION-X: What type of ideas might you add to the Menu system?''' Sin: An in-game menu has already been done (but still a little buggy) I have to fix it so it shows the last file and so it doesn't crash if you don't have enough files then I may add the ability to browse folders, both to improve the organization, and to add to the maximum number of ROMs per CD. '''EMULATION-X: Right now the maximum is 128?''' Sin: Well, technically 127 :) but yes..... with folders, each folder will be able to have up to 128 files so the number of ROMs possible is nearly infinite (up to the storage capacity of a CD) other than that, I'm trying to add a small speed increase. '''EMULATION-X: Thank you Sin for taking the time to answer all of My Questions, I really hope that anyone that reads this can understand what dedication you have and that this is only your hobby and you don't get paid to do this.''' Sin: Well, thank you for taking the time to interview little old me :) I hope Everyone will enjoy emulation on the Dreamcast :) [[Category:Emulator]] f68553a185506f773b6897bed55c4374207ba7c5 2757 2756 2023-03-04T01:04:55Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Sintendo| image=[[File:sintendo.jpg|center|250px]]| homepage=[http://sintendo.dcemulation.org/ Homepage]| version=0.10-pre2| downloads=[http://sintendo.dcemulation.org/files/BetaTest010-2.zip Plain Files]<br/>[http://sintendo.dcemulation.org/files/Sintendo-Source-August-18-2001.zip Source code]| release date=08/03/2001| author=Jamin Vander Berg (aka [[Sin]])| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} Sintendo was one of the earliest emulators for the Dreamcast console. It it a port of Snes9x by Jamin Vander Berg (aka [[Sin]]). It was made using the [[WinCE]] SDK. The newest version is Sintendo Beta v0.10 - Prerelease version 2 which was released on August 3, 2001. The Sintendo website is hosted by DCEmulation.com. Sintendo doesn't support sound or saving games. [[Sin]] planned to include both in a future version of Sintendo but he never released it. Here's some status information by [[Sin]]: *Memory allocation is working. *Port to dreamcast successfull. Little slow at the moment. *Features done are MOD emulation, Joystick Support and saving. *Little bit of sound and graphics done. Old versions of Sintendo can be downloaded from [http://sintendo.dcemulation.org/ the official site]. The official forums are still up, but hadn't had any activity since years. They can be found [http://pub21.ezboard.com/bdcsnes here] but all previous posts have gone lost. == Activity == Below is a post from [[Sin]] that he made on 27th December 2002. It is one of last posts he made in his own forum. His last post there was on 22th January 2003 responding to someone who had replied to this message. He has never been active again in any Dreamcast forum. The original topic can be found [http://web.petabox.bibalex.org/web/20041217131810/p210.ezboard.com/fdcsnesdcsnes.showMessage?topicID=99.topic here]. ''It has been a great deal of time since I have updated this website, reviewed the posts here, or even touched the code for Sintendo.'' ''In recent ponderings, I have wondered if what I have done is worth working further forward towards. While I am deeply satisfied with how far everything has come (some may not agree, but I doubt they are programmers), I still never got it as far as I had hoped.'' ''The Dreamcast is all but a dead system. Many of us still use ours, I pop a disc in and play from time to time, but all of the effort I've put into Sintendo in the past, while not wasted, may fall on deaf ears if I continue to pursue the project, so long after the consoles unfortunate demise.'' ''Work, as always, is a burden on a creative programmer's time and imagination. I'll not use that as an excuse for anything. I still program from time to time, but its been quite a while since I've approached anything that compares with the scope of Sintendo.'' ''Never before or since have I conceived a project with such determination to see it through to even as close a level of completion. Anyone who programs (and some who don't) should understand the year plus of plight that went into this project. I appreciate all of the support I have received over this time. I gratefully appreciate my host, dcemulation.com, for keeping this site up more than a year after a single update.'' ''I am by no means saying that Sintendo is a dead project. I am not quitting, per se. I am only trying to tell all of you, what few dedicated followers I may have left, that I have not worked on it for quite some time, and can't necessarily forsee any time in the future when I will. I can not even promise that Sintendo *will* ever be worked on (by me at least), but I'd like to think that that's not the case.'' ''I have been dedicated to games programming since the age of 15. Now, 25, I still work towards the same goal. Sintendo bore me priceless experience in the console programming market that I will take with me in the future. Where it will lead? I can't say for certain. I'd like to develop games for many years to come. Personally, and most importantly, I'd like to develop a game to completion. Perhaps we may some day see Sintendo on another console (although I currently own none to port it to). Time will tell.'' ''Thank you all again for all the support I've received. I apologize for lack of adequete postings as well as lack of decisiveness.'' ''Until another time,'' ''Sin'' ==Downloads== https://files.dcemulation.org/software/dreamcast/emulators/sintendo/BetaTest010-2.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/BetaTest010.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Build34.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-April-19-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-April-24-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-August-18-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-May-1-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/s9xs132.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendo-source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendo56.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta001source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta002.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobuild209.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobuild209source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sourcesnes9xwin.exe ==Interview== This is an interview with [[Sin]], the creator of Sintendo. It was taken in late 2001 by Emulation-X of GeoShock, a popular emulation site in these days. GeoShock went offline in early 2006, so we have published this interview here. '''Emulation-X: Why did you make Sintendo?''' Sin: I made Sintendo because I wanted to be able to play Super Nintendo games on my Dreamcast. I released Sintendo to the world because I imagined other people would like to as well. There was once a time when such a thing was only imaginable and I saw that I *could* do it... I used Snes9x because it is portable, maybe the development a lot easier The only other really useful SNES emulator is ZSNES, which may be better in some ways, but is far from portable. ZSNES is written primarily in x86 assembly, everything written in that way must be re-written to work on the Dreamcast. Snes9x was just a much more attractive option because it's written in C.I have had to do very little re-writing of the Snes9x code. I started most of my research on the forums of the "warez" sites. Dcisos.com had a development forum The portable version of Snes9x has a file called how2port.txt. Its like following instructions, kind of It's quite a bit more complicated than that. '''Emulation-X: Who made the a big Impact with you while making Sintendo?''' Sin: I'd have to say Gary, the author of Snes9x had a huge impact on me.The fact that he responded to my email suprised me, and while he hasn't given me any particular help... He has been very supportive...as well as creating the thing in the first place. Tubooboo has helped me solve a few of my most frustrating problems. Tubooboo's presence on the scene was also a great motivating force i wish a great deal of success to him with his project. '''Emulation-X: Tubooboo also has a Snes Emulator for the Dreamcast. Was this a race?''' Sin: The fact that he started it, however, spurred a great deal of competitiveness in me that was probably the direct cause of Sintendo being released on time there was probably an unspoken race between us. the race ended when Marcus won, by a half a day I released my emulator later that day, and then an improved version the next. It has sound and saving, two great feats,but I understand that the sound slows down the emulation somewhat and speed in controlled by a frameskip, which takes away some of the smoothness from the games. '''EMULATION-X: When did you get involved in Emulation?''' Sin: I don't know when really maybe around Nesticle.It ran on our P100 at good speed, it was fun to play all those old games even my mom loved it. Then emulators started coming out that emulated the SNES following in a loose sense of the term. I've used a lot of them,I've even considered doing SNES emulation myself. I had a few ideas but never the time to research all the ins and outs the SNES is a very complicated machine.I used to imagine that compiling a SNES cartridge into machine code would speed emulation a great deal...and it probably would...it is unfortunately not very practical . '''EMULATION-X: Besides making Sintendo (Snes for DC) are there any other Emulators that you might want to port in the future to the Dreamcast?''' Sin: I don't have any intention on porting another emulator to the DC.Though SNES emulation on the PS2 would be very cool...and certainly be less problematic that my orignal port I haven't exactly decided yet. I am a games programmer at heart. I love RPGs in specific and I can't play one without analysing it a great deal I've been programming rudementary RPGs since I first started programming and it is perhaps the reason I began programming in the first place. So I guess there's a good chance that may be my next route '''Emulation-X: What other Emus do you use besides Snes9x?''' Sin: I kind of like Pokemon, so sometimes I use the no$gb emulator, or whatever on the PC version you can run more than one gameboy...which makes trading useful, and I programmed a small app that switches the save files arround so I can play more than one save... and if I click one check box, I can trade without actually losing the pokemon I traded (i.e. Copy a Pokemon) '''EMULATION-X: What is your View on Utopia boot disk (DC-warez) and the hole shut down of the DC news web sites?''' Sin: The boot disk is a good thing, and I don't believe it is really illegal. News sites are news sites, and Sega has no right toshut them down for providing information regardless of the nature of that information '''EMULATION-X: Has Sega or Nintendo never tried to contact you ?''' Sin: No, but I have considered contacting them. Perhaps obtain a license for Sintendo... or get a job :) or licensing for future projects like the aforementioned RPG its an option i am looking into I'd imagine the people that use it for emulation will be using it for some time to come '''Emulation-X: What do you think about the Dreamcast Now?''' Sin: As a consumer system, it's closed to dead. No one really wants to spend any money on it any more the games have been released (illegally) for free. '''EMULATION-X: Do you think that Emulation and Warez kills a system?''' Sin: Yes and no. Warez killed a lot of profits Sega and its developers could have made. But then all those kids bought tons of accessories because they had extra money. Emulation is a program I don't think in and of itself emulation and emulators for the Dreamcast could kill the system But then, it's kindof like cheating at a game... You played it for a while and you're bored... so you want something new... So you cheat to make it more exciting... eventually (maybe sooner, maybe later) thats gets old too... but the game was already old in the first place if you catch my analogy, but I know I'll stick pick up my Dreamcast for years to come and play some old SNES games . '''EMULATION-X: Where did the name Sintendo come from?''' Sin: spankthemonkey, my web designer, thought of it. '''EMULATION-X: Do you plan on improving on Sintendo anytime soon?''' Sin: I'm still improving Sintendo almost every day there's a lot that still has to be done speed is an issue, no one wants to play a game (at least not for a great deal of time) if it's slow, saving should be implemented soon and I really want to be able to hear the music for ChronoTrigger while I'm playing. There are a few details that were left out from my first release I am covering those bases (and maybe throwing in a few extras) and I'll release in under a week. '''EMULATION-X: What type of ideas might you add to the Menu system?''' Sin: An in-game menu has already been done (but still a little buggy) I have to fix it so it shows the last file and so it doesn't crash if you don't have enough files then I may add the ability to browse folders, both to improve the organization, and to add to the maximum number of ROMs per CD. '''EMULATION-X: Right now the maximum is 128?''' Sin: Well, technically 127 :) but yes..... with folders, each folder will be able to have up to 128 files so the number of ROMs possible is nearly infinite (up to the storage capacity of a CD) other than that, I'm trying to add a small speed increase. '''EMULATION-X: Thank you Sin for taking the time to answer all of My Questions, I really hope that anyone that reads this can understand what dedication you have and that this is only your hobby and you don't get paid to do this.''' Sin: Well, thank you for taking the time to interview little old me :) I hope Everyone will enjoy emulation on the Dreamcast :) [[Category:Emulator]] 657bf06e59d2c2c1b91f44cbf0c5ba932deca50a 2758 2757 2023-03-04T01:05:05Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Sintendo| image=[[File:sintendo.jpg|center|250px]]| homepage=[http://sintendo.dcemulation.org/ Homepage]| version=0.10-pre2| downloads=[http://sintendo.dcemulation.org/files/BetaTest010-2.zip Plain Files]<br/>[http://sintendo.dcemulation.org/files/Sintendo-Source-August-18-2001.zip Source code]| release date=08/03/2001| author=Jamin Vander Berg (aka [[Sin]])| original=Snes9x Team<br/>(Snes9x)| systems=Super Nintendo| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} Sintendo was one of the earliest emulators for the Dreamcast console. It it a port of Snes9x by Jamin Vander Berg (aka [[Sin]]). It was made using the [[WinCE]] SDK. The newest version is Sintendo Beta v0.10 - Prerelease version 2 which was released on August 3, 2001. The Sintendo website is hosted by DCEmulation.com. Sintendo doesn't support sound or saving games. [[Sin]] planned to include both in a future version of Sintendo but he never released it. Here's some status information by [[Sin]]: *Memory allocation is working. *Port to dreamcast successfull. Little slow at the moment. *Features done are MOD emulation, Joystick Support and saving. *Little bit of sound and graphics done. Old versions of Sintendo can be downloaded from [http://sintendo.dcemulation.org/ the official site]. The official forums are still up, but hadn't had any activity since years. They can be found [http://pub21.ezboard.com/bdcsnes here] but all previous posts have gone lost. == Activity == Below is a post from [[Sin]] that he made on 27th December 2002. It is one of last posts he made in his own forum. His last post there was on 22th January 2003 responding to someone who had replied to this message. He has never been active again in any Dreamcast forum. The original topic can be found [http://web.petabox.bibalex.org/web/20041217131810/p210.ezboard.com/fdcsnesdcsnes.showMessage?topicID=99.topic here]. ''It has been a great deal of time since I have updated this website, reviewed the posts here, or even touched the code for Sintendo.'' ''In recent ponderings, I have wondered if what I have done is worth working further forward towards. While I am deeply satisfied with how far everything has come (some may not agree, but I doubt they are programmers), I still never got it as far as I had hoped.'' ''The Dreamcast is all but a dead system. Many of us still use ours, I pop a disc in and play from time to time, but all of the effort I've put into Sintendo in the past, while not wasted, may fall on deaf ears if I continue to pursue the project, so long after the consoles unfortunate demise.'' ''Work, as always, is a burden on a creative programmer's time and imagination. I'll not use that as an excuse for anything. I still program from time to time, but its been quite a while since I've approached anything that compares with the scope of Sintendo.'' ''Never before or since have I conceived a project with such determination to see it through to even as close a level of completion. Anyone who programs (and some who don't) should understand the year plus of plight that went into this project. I appreciate all of the support I have received over this time. I gratefully appreciate my host, dcemulation.com, for keeping this site up more than a year after a single update.'' ''I am by no means saying that Sintendo is a dead project. I am not quitting, per se. I am only trying to tell all of you, what few dedicated followers I may have left, that I have not worked on it for quite some time, and can't necessarily forsee any time in the future when I will. I can not even promise that Sintendo *will* ever be worked on (by me at least), but I'd like to think that that's not the case.'' ''I have been dedicated to games programming since the age of 15. Now, 25, I still work towards the same goal. Sintendo bore me priceless experience in the console programming market that I will take with me in the future. Where it will lead? I can't say for certain. I'd like to develop games for many years to come. Personally, and most importantly, I'd like to develop a game to completion. Perhaps we may some day see Sintendo on another console (although I currently own none to port it to). Time will tell.'' ''Thank you all again for all the support I've received. I apologize for lack of adequete postings as well as lack of decisiveness.'' ''Until another time,'' ''Sin'' ==Downloads== https://files.dcemulation.org/software/dreamcast/emulators/sintendo/BetaTest010-2.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/BetaTest010.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Build34.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-April-19-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-April-24-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-August-18-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/Sintendo-Source-May-1-2001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/s9xs132.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendo-source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendo56.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta001.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta001source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobeta002.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobuild209.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sintendobuild209source.zip https://files.dcemulation.org/software/dreamcast/emulators/sintendo/sourcesnes9xwin.exe ==Interview== This is an interview with [[Sin]], the creator of Sintendo. It was taken in late 2001 by Emulation-X of GeoShock, a popular emulation site in these days. GeoShock went offline in early 2006, so we have published this interview here. '''Emulation-X: Why did you make Sintendo?''' Sin: I made Sintendo because I wanted to be able to play Super Nintendo games on my Dreamcast. I released Sintendo to the world because I imagined other people would like to as well. There was once a time when such a thing was only imaginable and I saw that I *could* do it... I used Snes9x because it is portable, maybe the development a lot easier The only other really useful SNES emulator is ZSNES, which may be better in some ways, but is far from portable. ZSNES is written primarily in x86 assembly, everything written in that way must be re-written to work on the Dreamcast. Snes9x was just a much more attractive option because it's written in C.I have had to do very little re-writing of the Snes9x code. I started most of my research on the forums of the "warez" sites. Dcisos.com had a development forum The portable version of Snes9x has a file called how2port.txt. Its like following instructions, kind of It's quite a bit more complicated than that. '''Emulation-X: Who made the a big Impact with you while making Sintendo?''' Sin: I'd have to say Gary, the author of Snes9x had a huge impact on me.The fact that he responded to my email suprised me, and while he hasn't given me any particular help... He has been very supportive...as well as creating the thing in the first place. Tubooboo has helped me solve a few of my most frustrating problems. Tubooboo's presence on the scene was also a great motivating force i wish a great deal of success to him with his project. '''Emulation-X: Tubooboo also has a Snes Emulator for the Dreamcast. Was this a race?''' Sin: The fact that he started it, however, spurred a great deal of competitiveness in me that was probably the direct cause of Sintendo being released on time there was probably an unspoken race between us. the race ended when Marcus won, by a half a day I released my emulator later that day, and then an improved version the next. It has sound and saving, two great feats,but I understand that the sound slows down the emulation somewhat and speed in controlled by a frameskip, which takes away some of the smoothness from the games. '''EMULATION-X: When did you get involved in Emulation?''' Sin: I don't know when really maybe around Nesticle.It ran on our P100 at good speed, it was fun to play all those old games even my mom loved it. Then emulators started coming out that emulated the SNES following in a loose sense of the term. I've used a lot of them,I've even considered doing SNES emulation myself. I had a few ideas but never the time to research all the ins and outs the SNES is a very complicated machine.I used to imagine that compiling a SNES cartridge into machine code would speed emulation a great deal...and it probably would...it is unfortunately not very practical . '''EMULATION-X: Besides making Sintendo (Snes for DC) are there any other Emulators that you might want to port in the future to the Dreamcast?''' Sin: I don't have any intention on porting another emulator to the DC.Though SNES emulation on the PS2 would be very cool...and certainly be less problematic that my orignal port I haven't exactly decided yet. I am a games programmer at heart. I love RPGs in specific and I can't play one without analysing it a great deal I've been programming rudementary RPGs since I first started programming and it is perhaps the reason I began programming in the first place. So I guess there's a good chance that may be my next route '''Emulation-X: What other Emus do you use besides Snes9x?''' Sin: I kind of like Pokemon, so sometimes I use the no$gb emulator, or whatever on the PC version you can run more than one gameboy...which makes trading useful, and I programmed a small app that switches the save files arround so I can play more than one save... and if I click one check box, I can trade without actually losing the pokemon I traded (i.e. Copy a Pokemon) '''EMULATION-X: What is your View on Utopia boot disk (DC-warez) and the hole shut down of the DC news web sites?''' Sin: The boot disk is a good thing, and I don't believe it is really illegal. News sites are news sites, and Sega has no right toshut them down for providing information regardless of the nature of that information '''EMULATION-X: Has Sega or Nintendo never tried to contact you ?''' Sin: No, but I have considered contacting them. Perhaps obtain a license for Sintendo... or get a job :) or licensing for future projects like the aforementioned RPG its an option i am looking into I'd imagine the people that use it for emulation will be using it for some time to come '''Emulation-X: What do you think about the Dreamcast Now?''' Sin: As a consumer system, it's closed to dead. No one really wants to spend any money on it any more the games have been released (illegally) for free. '''EMULATION-X: Do you think that Emulation and Warez kills a system?''' Sin: Yes and no. Warez killed a lot of profits Sega and its developers could have made. But then all those kids bought tons of accessories because they had extra money. Emulation is a program I don't think in and of itself emulation and emulators for the Dreamcast could kill the system But then, it's kindof like cheating at a game... You played it for a while and you're bored... so you want something new... So you cheat to make it more exciting... eventually (maybe sooner, maybe later) thats gets old too... but the game was already old in the first place if you catch my analogy, but I know I'll stick pick up my Dreamcast for years to come and play some old SNES games . '''EMULATION-X: Where did the name Sintendo come from?''' Sin: spankthemonkey, my web designer, thought of it. '''EMULATION-X: Do you plan on improving on Sintendo anytime soon?''' Sin: I'm still improving Sintendo almost every day there's a lot that still has to be done speed is an issue, no one wants to play a game (at least not for a great deal of time) if it's slow, saving should be implemented soon and I really want to be able to hear the music for ChronoTrigger while I'm playing. There are a few details that were left out from my first release I am covering those bases (and maybe throwing in a few extras) and I'll release in under a week. '''EMULATION-X: What type of ideas might you add to the Menu system?''' Sin: An in-game menu has already been done (but still a little buggy) I have to fix it so it shows the last file and so it doesn't crash if you don't have enough files then I may add the ability to browse folders, both to improve the organization, and to add to the maximum number of ROMs per CD. '''EMULATION-X: Right now the maximum is 128?''' Sin: Well, technically 127 :) but yes..... with folders, each folder will be able to have up to 128 files so the number of ROMs possible is nearly infinite (up to the storage capacity of a CD) other than that, I'm trying to add a small speed increase. '''EMULATION-X: Thank you Sin for taking the time to answer all of My Questions, I really hope that anyone that reads this can understand what dedication you have and that this is only your hobby and you don't get paid to do this.''' Sin: Well, thank you for taking the time to interview little old me :) I hope Everyone will enjoy emulation on the Dreamcast :) [[Category:Emulator]] e8facd4d3b4539f3e9083aa34932d20f545ad2aa DC64 0 914 2759 2075 2023-03-04T01:10:18Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC64| image=No Screenshot Available| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=Beta 4| downloads=See List<br/>| release date=11/01/01| author=BigBoy| original=N/A| systems=Commodore 64| best=Unknown| isactive=No }} Developer: BigBoy<br/> Version: Beta 4<br/> Last Updated: 11-01-01<br/> Description: Finally, a commodore 64 emulator for dreamcast, this version is just a test demo, showing you of what it can do so far. Latest Status: <br/> Still Sanxion, running nice and smooth now. Only a few games do just now, speed changes depending on the game. Uridium and Sanxion both seem to be at full "smooth" speed. However there is still no input, and this WILL slow it down again...*sigh* I will try and add basic input soon. There is no Sprite-2-???? collision. This would slow things down a LOT! <br/> =Downloads= * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64_V1.zip Plain Files] =Old versions= * Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64beta4.zip Plain Files] Selboot:No 345kb * Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64beta4DJ.zip Disk Juggler] Selfboot:Yes 370kb * Beta 3 - https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64beta3.zip Plain Files] Selfboot:No 357kb * Beta 3 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/DC64DJ.zip Disk Juggler] Selfboot:Yes 212kb * First release - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/DC64sbb.zip Plain Files] Selfboot:No 208kb SelfBoot Buddy INI included. [[Category:Emulator]] 513fe702b71f93a4e4bb559f9d58b6159e4da2d8 2760 2759 2023-03-04T01:11:08Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC64| image=No Screenshot Available| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=V1| downloads=See List<br/>| release date=4/18/03| author=BigBoy| original=N/A| systems=Commodore 64| best=Unknown| isactive=No }} Description: Okay, not the version I was hoping for.... but Ive run out of time, so rather than nothing... here it is... same controls as DreamSpec, but be warned, returning to the main menu is..... "iffy" Place FE.BMP in the root.. dc64.bin is NOT scrambled. T64, P00 and PRG's work....well.. mostly... START key should get you past 90% of trainers etc... keyboard is supported, but not at the same time as joypad. Oh well... its crap, but its here.... and sorry... no support on this one.. Bigboy =Downloads= * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64_V1.zip Plain Files] =Old versions= * Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64beta4.zip Plain Files] Selboot:No 345kb * Beta 4 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64beta4DJ.zip Disk Juggler] Selfboot:Yes 370kb * Beta 3 - https://files.dcemulation.org/software/dreamcast/emulators/dc64/dc64beta3.zip Plain Files] Selfboot:No 357kb * Beta 3 - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/DC64DJ.zip Disk Juggler] Selfboot:Yes 212kb * First release - [https://files.dcemulation.org/software/dreamcast/emulators/dc64/DC64sbb.zip Plain Files] Selfboot:No 208kb SelfBoot Buddy INI included. [[Category:Emulator]] 6d301065562517f4b04c3208a7fafd9063b50d07 DreamFrodo 0 916 2761 2077 2023-03-04T01:12:51Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamFrodo| image=N/A| homepage=[http://frodo.boob.co.uk/ Homepage]| version=V0.94| downloads=See List<br/>| release date=Unknown| author=Tolga Abaci| original=(Frodo)| systems=Commodore 64| best=Unknown| isactive=Unknown }} *Developer: Tolga Abaci *Updated: 26-07-03 *Description: A port of the Commodore 64 emulator Frodo. =Downloads= * v0.94 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamfrodo/DreamFrodo.0.94.bin.st.zip Plain Files] Binary "standard" 200kb * v0.94 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamfrodo/DreamFrodo.0.94.bin.pc.zip DiscJuggler] Binary "precise cycle" 200kb * v0.94 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamfrodo/DreamFrodo.0.94.src.zip Source] Source 547kb [[Category:Emulator]] 7dfdcedb7f27b344e2aa5b80639f9280c102f180 Panera 64 0 918 2762 2079 2023-03-04T01:14:27Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Panera 64| image=No Screenshot Available| homepage=[http://www.dreamcast.es/news.php?readmore=124 Homepage]| version=Alpha 01| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/panera64/panera6401a.rar Plain Files]| release date=07/31/2008| author=[[ron]]| original=[http://frodo.cebix.net/ Frodo]/[[DreamFrodo]]<br />(Christian Bauer)| systems=Commodore 64| best=Probarbly.| refreshrate=50Hz / 60Hz| isactive=Unknown }} [[ron]] took [[DreamFrodo]] 0.94 by [[Tolga Abaci]], which was built with [[KallistiOS]] 0.91, tweaked some code and made it use a modern toolchain. The result is Panera 64 - in its first alpha version it runs fullspeed without frameskip, supporting two pads and the Dreamcast keyboard. There's even a virtual keyboard you can access by pressing X on your controller and also a main menu by pressing Start. A German and a French version are planned for the future. You can discuss about Panera 64 [http://dcemulation.org/phpBB/viewtopic.php?f=72&t=97628 here]. Below is video of Panera 64: *http://www.youtube.com/watch?v=4tl0xhaNAwk efeffc448b20ad4e4aa1ba3844a5381a023cd92f Whack-a-Mole 0 910 2763 2070 2023-03-04T01:18:35Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Whack-a-Mole| image=N/A| homepage=Unknown| version=0.900| downloads=[http://www.dcemulation.org/files/emulators/wam.bin.zip Plain Files(Scrambled)]| release date=Unknown| author=[[Toastman]]| original=N/A | systems=Chip 8| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} *Developer: Toastman *Updated: 16-02-04 *Description: A Chip 8 emulator that comes with a bunch of games. =Downloads= * v0.900 - [https://files.dcemulation.org/software/dreamcast/emulators/whackamole/wam.bin.zip Plain Files(Scrambled)] 510kb 01/13/2004? * v0.900 - [https://files.dcemulation.org/software/dreamcast/emulators/whackamole/wam.elf.zip Plain Files(Raw ELF)] 520kb 01/13/2004? * v0.500 - [https://files.dcemulation.org/software/dreamcast/emulators/whackamole/wam0500.cdi.zip DiscJuggler] 01/13/2004? * v0.500 - [https://files.dcemulation.org/software/dreamcast/emulators/whackamole/wam0500.nrg.zip Nero] 01/13/2004? * ??? - [https://files.dcemulation.org/software/dreamcast/emulators/whackamole/Whack-a-Mole.zip ELF] 1/8/2004 [[Category:Emulator]] 2d47830663fa5f52f3d7e5dc306bb75e676d4a91 LynxMESS 0 905 2764 2733 2023-03-04T01:21:55Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=LynxMESS| image=N/A| homepage=Unknown| version=v1| downloads=[http://www.dcemulation.org/files/emulators/lynxdc.zip Plain files]| release date=Unknown| author=Ian Micheal| original=M.A.M.E. source code 0.71| systems=Atari Lynx| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ian Micheal Updated: 16-02-04 Description: An emulator for the handheld Atari Lynx. This is based off Ice88/Warmtoes work on M.E.S.S. and M.A.M.E. source code 0.71. It's running at about 36fps, which is a great speed for lynx. The only game tested is rygar, so other game speeds may vary. Speed: 70% Sound: Unknown Links: [http://www.dcemulation.org/phpBB/viewtopic.php?t=36622 Mess build Atari lynx release!] =Downloads= * v1 - [https://files.dcemulation.org/software/dreamcast/emulators/lynxmess/lynxdc.zip Plain files] * v1 - [https://files.dcemulation.org/software/dreamcast/emulators/lynxmess/lynxsrcdiff.rar Source] [[category:emulator]] 1ffd3edaf1e954ef6fdf6cd92283c9b1f00909f0 NesterDC 0 808 2765 2725 2023-03-04T01:23:33Z Unknown user 0 /* Historical Files */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.tar.gz Source Code] 7.1 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.1-sdl.tar.gz Source Code] 7.1.1 (SDL) *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC7.1DJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7.1Nero.zip Nero] | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Historical Files== * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.zip Plain Files] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.tar.gz Source Code] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7dj.zip DiscJuggler] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7nero.zip Nero] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC.exe Best Damned Tutorial (Windows)] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-1ST_READ.BIN.zip 1ST_READ.BIN] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-PAL-1ST_READ.BIN.zip 1ST_READ.BIN] (PAL) * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0.tar.gz Source Code] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1-1ST_READ.BIN.zip 1ST_READ.BIN] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1.tar.gz Source Code] * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_src.zip Source Code] - 6/03/01 * 3.0t3 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-3.0t3.zip Plain Files] * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1.zip Plain Files] - 2/20/01 BROKEN * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0.zip Plain Files] * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 5.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-5.0.tar.gz Source Code] - 12/03/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 {{DCWiki:BrokenInternalLinks}} 5df3450aafdf6c731d2a2e08c0321807c0c2800a 2768 2765 2023-03-04T01:33:04Z Unknown user 0 /* Historical Files */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=NesterDC| image=[[Image:Nester3-4.jpg|center|250px]]| homepage=[http://www.pqrs.org/tekezo/dreamcast/software/nesterdc/ Homepage]| version=7.1| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1pb.zip Plain Files] 7.1+ *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.tar.gz Source Code] 7.1 *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.1-sdl.tar.gz Source Code] 7.1.1 (SDL) *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC7.1DJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7.1Nero.zip Nero] | release date=12/02/02| author=[[Takayama Fumihiko]]<br>(formerly [[Ken Friece]])| original=[http://web.archive.org/web/20040129112711/http://nester.dranalli.com/ Nester] by<br/>Darren Ranalli| systems=NES, Famicom| NTSCVGAPAL=NTSC| best=Yes.| isactive=No }} NesterDC emulates the NES and Famicom. After [[Ken Friece]] left the project in late 2001, [[Takayama Fumihiko]] took over and implemented save states, game genie codes and better compatibility over the span of the 4.0, 5.0, 6.0 and 7.0 releases. The emulator now features excellent speed and sound emulation and is most notable as being the best [NES] emulator for the Dreamcast. Early 2003, [[Warmtoe]] released a modified NesterDC 7.1 simply called NesterDC 7.1+ which added support for Dreamcast lightguns. [[Scherzo]] updated NesterDC 7.1 and released [[NesterDC SE|NesterDC Special Edition]] in late 2005 but had been criticized because of it's lack of directory listing for ROMs that are not in SE's master list, which are mostly game hacks and translations. The problem has been address recently by Christuserloeser by releasing an update titled "unofficial 1.1" of that changes to the main menu and implementation of SE's hidden directory listing ROM browser [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=97683 posted] by Scherzo in August of '08. '''Features:''' *GameGenie *NNNJester cheatcode support *Bilinear filtering *Normal save to VMU *Savestate to VMU *Savestate to DC memory *Autofire *Up to 4 Players *Nearly Perfect emulation ==Controls== '''Main Menu''' * A: ROM menu * X: option menu * B: VMU menu * Y: credit * START + Y + L + R: reset '''ROM Menu''' * A: select directory or ROM * Y: move to the parent directory * X + UP/DOWN/LEFT/RIGHT: high speed cursor move * analog: adjust cursor wait '''In-Game''' [Dreamcast Controller] * X: NES B * A: NES A * Y: NES SELECT * START: NES START * UP/DOWN/LEFT/RIGHT: same as DC * L: toggle-autofire-mode * L + R + START: return to main menu * analog: change frameskip ** UP: 'no skip' ** DOWN: 'auto x2.0' ** RIGHT: 'auto x1.0' ** LEFT: 'auto x1.5' ** LEFT + R: 'auto x4.0' * B + R: quick save menu * Y + R: VMU state save menu * X + R: system menu * A + R: option menu * START + R: cheat menu '''In-Game''' [Arcade Stick] * X: NES B * Y: NES A * C: toggle-autofire-mode * Z: NES SELECT * START: NES START * A: NES START * UP/DOWN/LEFT/RIGHT: same as DC ==Historical Files== * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.zip Plain Files] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-7.0.tar.gz Source Code] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7dj.zip DiscJuggler] * 7.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NDC7nero.zip Nero] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/NesterDC.exe Best Damned Tutorial (Windows)] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-bin.zip Plain Files] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-1ST_READ.BIN.zip 1ST_READ.BIN] * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0-PAL-1ST_READ.BIN.zip 1ST_READ.BIN] (PAL) * 6.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-6.0.tar.gz Source Code] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1-1ST_READ.BIN.zip 1ST_READ.BIN] * 5.0-pre1 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-5.0-pre1.tar.gz Source Code] * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-ntsc-1ST_READ.BIN.zip Plain Files] - 11/08/01 * 4.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/dcnesterdc-4.0-beta-pal-1ST_READ.BIN.zip Plain Files] (PAL) - 11/08/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_dj.zip DiscJuggler image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_nero.zip Nero image] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_bin.zip Plain Files] - 6/03/01 * 3.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-v3_src.zip Source Code] - 6/03/01 * 3.0t3 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc-3.0t3.zip Plain Files] * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_dj.zip DiscJuggler image] - 3/14/01 * 2.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v2_bin.zip Plain Files] - 3/14/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1_dj.zip DiscJuggler image] - 2/20/01 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/nesterdc/nesterdc_v1.zip Plain Files] - 2/20/01 BROKEN * 6.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-6.0-PAL.zip Plain Files] (PAL) * 5.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-5.0.tar.gz Source Code] - 12/03/01 * 4.0 - [http://dcemulation.org/1-newsdump/QRandom/Dreamcast%20Emulators/NES/NesterDC/nesterdc-4.0.tar.gz Source Code] - 11/08/01 {{DCWiki:BrokenInternalLinks}} c1b68caecaefbcde69144a5d1b99802a28427e8e FMSX DC 0 966 2766 2146 2023-03-04T01:30:22Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=fMSX DC| image=N/A| homepage=Unknown| version=Beta 1| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/fmsxdc/fmsxdc.zip Plain Files]| release date=Unknown| author=Arnon Cardoso| original=fMSX| systems=MSX| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Arnon Cardoso Version: Beta 1 Last Updated: February 19, 2002 Description: A port of the MSX emulator fMSX Status: *Used Stored Queues to improve performance. *Changed Z80 engine to not use a big switch but the result was disappointing. *MSX Joystick support. If you have two DC joysticks the first will act as of DreamMSX and the second can be used as MSX Joy A or B (selectable using the GUI). *GameMaster II SRAM save to VMU, using NesterDC VMU code. *Better GUI (?) than DreamMSX. Besides the options offered by DreamMSX you can also: ** - select MSX version up to 2+ (2+ emulation is partial though). ** - Synchronize the video updates to a frequency (50 or 60). *FM sound. *Disk swap after the emulation has started. *MSX 2+ screen modes. *256 files limit to roms and disks (each one). '''Make sure you have the controllers and vmu connected when booting fMSX for DC.''' =Downloads= * Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/fmsxdc/fmsxdc.zip Plain Files] * Beta 1 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/fmsxdc-scrm.zip Plain Files ] (pre-scrambled) [[category:emulator]] 0e0f870d9b6210e3425a3451470c947f3b72ddb7 2767 2766 2023-03-04T01:30:47Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=fMSX DC| image=N/A| homepage=Unknown| version=Beta 1| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/fmsxdc/fmsxdc.zip Plain Files]| release date=Unknown| author=Arnon Cardoso| original=fMSX| systems=MSX| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} *Developer: Arnon Cardoso *Version: Beta 1 *Last Updated: February 19, 2002 *Description: A port of the MSX emulator fMSX Status: *Used Stored Queues to improve performance. *Changed Z80 engine to not use a big switch but the result was disappointing. *MSX Joystick support. If you have two DC joysticks the first will act as of DreamMSX and the second can be used as MSX Joy A or B (selectable using the GUI). *GameMaster II SRAM save to VMU, using NesterDC VMU code. *Better GUI (?) than DreamMSX. Besides the options offered by DreamMSX you can also: ** - select MSX version up to 2+ (2+ emulation is partial though). ** - Synchronize the video updates to a frequency (50 or 60). *FM sound. *Disk swap after the emulation has started. *MSX 2+ screen modes. *256 files limit to roms and disks (each one). '''Make sure you have the controllers and vmu connected when booting fMSX for DC.''' =Downloads= * Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/fmsxdc/fmsxdc.zip Plain Files] * Beta 1 - [https://files.dcemulation.org/software/dreamcast/emulators/fmsxdc/fmsxdc-scrm.zip Plain Files] (pre-scrambled) [[category:emulator]] 76c0c6f84596e3c3bf1a479fb5dddca95b38de09 Dream MSX 0 965 2769 2145 2023-03-04T01:36:18Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamMSX!| image=N/A| homepage=Unknown| version=0.2g| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreammsx/dreammsxMAE.zip Plain Files]| release date=Unknown| author=Joe Kwanten| original=N/A | systems=MSX| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} *Developer: Jos Kwanten *Version: 0.2g *Last Updated: 09-18-01 *Description: An MSX emulator for your dreamcast. This is one of the greatest ports ever. It comes with full sound and music and its running at FULL SPEED. This release comes with metal gear and paradus built in. *Status: There is sound and runs at full speed. =Downloads= *[https://files.dcemulation.org/software/dreamcast/emulators/dreammsx/dreammsxMAE.zip Plain Files] 0.2g *[https://files.dcemulation.org/software/dreamcast/emulators/dreammsx/dreammsx02f.zip Plain Files] 0.2f [[Category:Emulator]] 66dd112dfa8347031cf9eaa8cc0eb8ad43713376 UMSX 0 921 2770 2083 2023-03-04T01:39:24Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=uMSX| image=[[Image:umsx.png|center|250px]]| homepage=[http://www.developia.info/viewtopic.php?f=9&t=19 Homepage]| version=0.2| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/umsx/uMSX-DCbin-0.2.tar.bz2 Plain Files]| release date=07/01/2008| author=[[Uguru]]| original=[http://fms.komkon.org/fMSX/ fMSX]<br />(Marat Fayzulin)| systems=MSX| best=Probarbly.| refreshrate=50Hz / 60Hz| isactive=Unknown }} uMSX is a Mircosoft MSX emulator. It is based on Marat Fayzulin's fMSX emulator and was ported by [[Uguru]]. It supports sound and saving to a VMU and has a nice user interface. a5db35c92e896475cd8998a4f6e86618dd38547e Neko Project II 0 909 2771 2069 2023-03-04T01:47:23Z Unknown user 0 /* Downloads */ wikitext text/x-wiki A full speed PC-9801 emulator for Dreamcast based on [http://www.retropc.net/yui/np2.html Neko Project II]. ''Via [http://en.wikipedia.org/wiki/PC-9801 Wikipedia]:''<br/> "The NEC PC-9801 (or the PC-98 for short) is a Japanese microcomputer manufactured by NEC. It first appeared in 1982, and employed an 8086 CPU. It ran at a clock speed of 5 MHz, with two µPD7220 display controllers (one for text, the other for video graphics), and shipped with 128 KB of RAM, expandable to 640 KB. Its 8-color display had a maximum resolution of 640×400 pixels. Its successor, the PC-9801E, which appeared in 1983, employed an 8086-2 CPU, which could selectably run at a speed of either 5 or 8 MHz." ==Needed files== In data directory *BIOS.ROM *FONT.ROM or FONT.BMP or FONT.TMP *SOUND.ROM (optional) ==How to burn== ''W.I.P.'' ==Downloads== *0.13.05.12 - [https://files.dcemulation.org/software/dreamcast/emulators/nekoproject2/np2-0.13.05.12-dc-sd-plainfiles.zip Plain files] for SD card *0.13.05.12 - [https://files.dcemulation.org/software/dreamcast/emulators/nekoproject2/np2-0.13.05.12-dc-sd-source.tar.bz2 Source] *0.13.05.10 - [https://files.dcemulation.org/software/dreamcast/emulators/nekoproject2/np2-0.13.05.10-dc-plainfiles.zip Plain files] for CD *0.13.05.10 - [https://files.dcemulation.org/software/dreamcast/emulators/nekoproject2/np2-0.13.05.10-dc-source.tar.bz2 Source] *0.13.04.10 - [https://files.dcemulation.org/software/dreamcast/emulators/nekoproject2/np2-0.13.04.10-dc-plainfiles.zip Plain files] for CD *0.13.04.10 - [https://files.dcemulation.org/software/dreamcast/emulators/nekoproject2/np2-0.13.04.10-dc-source.tar.bz2 Source] ==Links== Neko Project II Dreamcast page *http://neko.sourceforge.net/np2.html Neko Project II official website *http://www.retropc.net/yui/np2.html Sourceforge project page *http://sourceforge.net/projects/neko/ List of PC-9801 games'': Wikipedia'' *http://en.wikipedia.org/wiki/Category:NEC_PC-9801_games c9b7bae34d9b0e4702bffeee5267c0d9a193ce53 DreamSpec 0 964 2772 2144 2023-03-04T01:48:57Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSpec| image=N/A| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=1.0| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/Dspecv1-sound.zip Plain Files]| release date=Unknown| author=BigBoy| original=N/A | systems=Spectrum| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: BigBoy Version: 1.0 Last Updated: 6-11-02 Description: The Best Spectrum emulator on the Dreamcast! Status: Now has SOUND and supports spectrum BRIGHT mode Supports RGB and VGA, as well as Loading and Saving to VMS! ==Files== * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/Dspecv1-sound.zip Plain Files] No games included. * 0.0005 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/dreamspecCDIv0.5.zip DiscJuggler] 200 Games Inlcuded =Old Versions= * 0.0003 - [http://www.dcemulation.org/dl/dl.php3?url=files/emulators/DreamSpec3Files.zip Plain Files] 200kb No games included. [[Category:Emulator]] 9fa9b1cbc927906e7244073c92cc9049135fd0ee 2773 2772 2023-03-04T01:49:05Z Unknown user 0 /* Old Versions */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSpec| image=N/A| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=1.0| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/Dspecv1-sound.zip Plain Files]| release date=Unknown| author=BigBoy| original=N/A | systems=Spectrum| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: BigBoy Version: 1.0 Last Updated: 6-11-02 Description: The Best Spectrum emulator on the Dreamcast! Status: Now has SOUND and supports spectrum BRIGHT mode Supports RGB and VGA, as well as Loading and Saving to VMS! ==Files== * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/Dspecv1-sound.zip Plain Files] No games included. * 0.0005 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/dreamspecCDIv0.5.zip DiscJuggler] 200 Games Inlcuded [[Category:Emulator]] 235e26d13532c3fb7837cddc40ef3c7ac445e8c6 2774 2773 2023-03-04T01:49:20Z Unknown user 0 /* Files */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamSpec| image=N/A| homepage=[http://classicgaming.dcemulation.org/ Homepage]| version=1.0| downloads=[http://www.dcemulation.org/dl/dl.php3?url=files/emulators/Dspecv1-sound.zip Plain Files]| release date=Unknown| author=BigBoy| original=N/A | systems=Spectrum| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Developer: BigBoy Version: 1.0 Last Updated: 6-11-02 Description: The Best Spectrum emulator on the Dreamcast! Status: Now has SOUND and supports spectrum BRIGHT mode Supports RGB and VGA, as well as Loading and Saving to VMS! ==Files== * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/Dspecv1-sound.zip Plain Files] No games included. * 0.0005 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/dreamspecCDIv0.5.zip DiscJuggler] 200 Games Inlcuded * 0.0003 - [https://files.dcemulation.org/software/dreamcast/emulators/dreamspec/DreamSpec3Files.zip Plain Files] No games included. [[Category:Emulator]] 1143451ccaf50a9d5f5108f55ccd17241adaf0c4 Spectrum 128k 0 967 2775 2147 2023-03-04T01:50:33Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Spectrum 128k!| image=N/A| homepage=[http://imrtechnology.ngemu.com/ Homepage]| version=v1| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/spectrum128k/spec128ktv.rar Plain Files(Scrambled)]| release date=Unknown| author=Ian Micheal| original=N/A | systems=Sinclair Spectrum| best=No| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ian Micheal Updated: 16-02-04 Description: A Speccy128k emu. =Downloads= * v1 - [https://files.dcemulation.org/software/dreamcast/emulators/spectrum128k/spec128ktv.rar Plain Files(Scrambled)] [[Category:emulator]] 74dd7275f5e0b57b6a23376a9502a1bfd8884b6f ZX-Ishspectrum 0 944 2776 2109 2023-03-04T01:51:17Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=ZX-Ishspectrum| image=N/A| homepage=Unknown| version=1.0| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/zxishspectrum/zx-ishpectrum_1.0.zip Plain Files]| release date=Unknown| author=Ishmair| original=N/A | systems=zx-spectrum 48k| best=Unknown| refreshrate=''Unknown| isactive=''Unknown| }} Developer: Ishmair Version: 1.0 Last Updated: 11-27-01 Description: zx-spectrum 48k for the PAL dreamcast. Includes: * Own motor Z80 in assembler. * Motor of sound and graficos with also overscan (multiple colors in line) in assembler. * Contended memory emulated (it needs adjustments). * It supports to formats z80 v1, v2, v3 and sna of 48k, single load at the moment. * Trim of screen. * Single you need pad dreamcast to play, in fact it does not support the keyboard of dreamcast, as I do not have one I cannot program it, and I do not think to buy it. * Joystick kempston emulado en pad analogico y boton A. * Joystick kempston emulado en pad analogico y boton A. * Pad digital and bellboys X, and, b are redefinibles like any key of the spectrum. * START invokes menu. =Downloads= * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/zxishspectrum/zx-ishpectrum_1.0.zip Plain Files] Selfboot:No 64kb [[category:Emulator]] da65ea5f93c10b93357088c3343e501fff3d0093 DreamZZT 0 1194 2777 2425 2023-03-04T01:54:41Z Unknown user 0 wikitext text/x-wiki *Developer: Sam Steele *Version that we have here: 2.0 *Description: A recreation of the ZZT engine for the Dreamcast. ==Files== *[https://files.dcemulation.org/software/dreamcast/emulators/dreamzzt/dreamzzt-2.0-rc1n.zip Nero Image] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamzzt/dreamzzt-2.0-rc1p.zip Plain files] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamzzt/dreamzzt-1.0.tar.gz Plain Files (v 1.0)] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamzzt/dreamzzt-1.0-src.tar.gz Source (v1.0)] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamzzt/dreamzzt-romdisk.bin Romdisk (v 1.0?)] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamzzt/dreamzzt-tag-demo.tar.gz Tag Demo (recovered from original 2.0 release?)] 0cf655fece6f7532fe45d728211ab63b461f1c78 FreeSCI 0 911 2778 2071 2023-03-04T02:02:08Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FreeSCI| image=| homepage=[http://freesci.linuxgames.com/?page=main Homepage]| version=0.6.4| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4-dc.zip Plain Files]<br/>*[https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4.tar.bz2 Source] | release date=05/18/08| author=Walter van Niftrik| original=[http://freesci.linuxgames.com/?page=main FreeSCI]| systems=SCI0 based adventure games| NTSCVGAPAL=Unknown| firstversion=Unknown| best=No, [[ScummVM]]| isactive=No| }} An interpreter for SIERRA adventure games using ''Sierra's Creative Interpreter'' (SCI), ported to Dreamcast by Walter van Niftrik (aka Phantom). ==About FreeSCI== ''Via [http://en.wikipedia.org/wiki/FreeSCI#Related_software Wikipedia]:''<br/> "FreeSCI is an open source engine that can run SCI0 games. FreeSCI works on Linux/Unix, Microsoft Windows, Sega Dreamcast, and GP32." "An open source program called [http://en.wikipedia.org/wiki/SCI_Studio SCI Studio] is available that lets users create games that are based on the SCI0 engine. SCI Studio is designed for Windows. On Linux, using Wine version 20050830, SCI Studio seems to work for editing games, but not for testing or running them. The workaround is to use SCI Studio for development and FreeSCI for game testing." ==Supported Games== ''List from: [http://freesci.linuxgames.com/?page=faq#entry-Whichgamescanthemostrecent'stable'version(0.3.5)run? freesci.linuxgames.com]'' *Leisure Suit Larry 2 *Leisure Suit Larry 3 *Police Quest 2 *King's Quest 4 *Quest for Glory 1/Hero's Quest *Space Quest 3 *Hoyle's Book of Games *The Colonel's Bequest *Conquest of Camelot *Hoyle's Book of Games 2 *Codename: Iceman ==SCI Studio== ''Via [http://www.bripro.com/scistudio/ SCI Studio website]:''<br /> "Have you ever wanted to make an adventure game like Sierra's King's Quest, Space Quest, Police Quest, Leisure Suit Larry or Quest for Glory? Well, now you can! With SCI Studio, you can create games using the exact same engine Sierra used! If you aren't familiar with SCI Studio, check out the [http://www.bripro.com/scistudio/faq.php FAQ page]." ''Via [http://en.wikipedia.org/wiki/SCI_Studio Wikipedia]:''<br /> "SCI Studio, software intended for creating games that execute using the classic Sierra's Creative Interpreter, was originally the progeny of Brian Provinciano. The software was worked on by Provinciano for many years, but on 25 March 2006 he announced on his website the cessation of work on his part, and released the complete archive of the SCI Studio source-code into the public domain (which contained much progress in the development of the program, which was never before seen in an official release). SCI Studio can also be considered an IDE for SCI Games for Microsoft Windows Operating Systems. All games created with SCI Studio run with Sierra's SCI0 Interpreter (SCIV.EXE) and the open source interpreter for Windows/MacOS/Linux/Sega's DreamCast and more, FreeSCI." ==Files== *0.6.4 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4-dc.zip Plain Files] *0.6.4 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4.tar.bz2 Source] *0.3.5 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.3.5-dc.zip Plain Files] *0.3.5 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.3.5.tar.bz2 Source] ==Links== Wikipedia SCI article: *http://en.wikipedia.org/wiki/FreeSCI List of SCI Games: *http://en.wikipedia.org/wiki/SCI_Games SCI Studio website: *http://www.bripro.com/scistudio/ FreeSCI merge with ''ScummVM?'': *http://www.scummvm.org/faq/#2_4 067cfe06c94be4151d4851f2adcd78758f8d9600 2779 2778 2023-03-04T02:02:18Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FreeSCI| image=| homepage=[http://freesci.linuxgames.com/?page=main Homepage]| version=0.6.4| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4-dc.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4.tar.bz2 Source] | release date=05/18/08| author=Walter van Niftrik| original=[http://freesci.linuxgames.com/?page=main FreeSCI]| systems=SCI0 based adventure games| NTSCVGAPAL=Unknown| firstversion=Unknown| best=No, [[ScummVM]]| isactive=No| }} An interpreter for SIERRA adventure games using ''Sierra's Creative Interpreter'' (SCI), ported to Dreamcast by Walter van Niftrik (aka Phantom). ==About FreeSCI== ''Via [http://en.wikipedia.org/wiki/FreeSCI#Related_software Wikipedia]:''<br/> "FreeSCI is an open source engine that can run SCI0 games. FreeSCI works on Linux/Unix, Microsoft Windows, Sega Dreamcast, and GP32." "An open source program called [http://en.wikipedia.org/wiki/SCI_Studio SCI Studio] is available that lets users create games that are based on the SCI0 engine. SCI Studio is designed for Windows. On Linux, using Wine version 20050830, SCI Studio seems to work for editing games, but not for testing or running them. The workaround is to use SCI Studio for development and FreeSCI for game testing." ==Supported Games== ''List from: [http://freesci.linuxgames.com/?page=faq#entry-Whichgamescanthemostrecent'stable'version(0.3.5)run? freesci.linuxgames.com]'' *Leisure Suit Larry 2 *Leisure Suit Larry 3 *Police Quest 2 *King's Quest 4 *Quest for Glory 1/Hero's Quest *Space Quest 3 *Hoyle's Book of Games *The Colonel's Bequest *Conquest of Camelot *Hoyle's Book of Games 2 *Codename: Iceman ==SCI Studio== ''Via [http://www.bripro.com/scistudio/ SCI Studio website]:''<br /> "Have you ever wanted to make an adventure game like Sierra's King's Quest, Space Quest, Police Quest, Leisure Suit Larry or Quest for Glory? Well, now you can! With SCI Studio, you can create games using the exact same engine Sierra used! If you aren't familiar with SCI Studio, check out the [http://www.bripro.com/scistudio/faq.php FAQ page]." ''Via [http://en.wikipedia.org/wiki/SCI_Studio Wikipedia]:''<br /> "SCI Studio, software intended for creating games that execute using the classic Sierra's Creative Interpreter, was originally the progeny of Brian Provinciano. The software was worked on by Provinciano for many years, but on 25 March 2006 he announced on his website the cessation of work on his part, and released the complete archive of the SCI Studio source-code into the public domain (which contained much progress in the development of the program, which was never before seen in an official release). SCI Studio can also be considered an IDE for SCI Games for Microsoft Windows Operating Systems. All games created with SCI Studio run with Sierra's SCI0 Interpreter (SCIV.EXE) and the open source interpreter for Windows/MacOS/Linux/Sega's DreamCast and more, FreeSCI." ==Files== *0.6.4 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4-dc.zip Plain Files] *0.6.4 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.6.4.tar.bz2 Source] *0.3.5 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.3.5-dc.zip Plain Files] *0.3.5 - [https://files.dcemulation.org/software/dreamcast/emulators/freesci/freesci-0.3.5.tar.bz2 Source] ==Links== Wikipedia SCI article: *http://en.wikipedia.org/wiki/FreeSCI List of SCI Games: *http://en.wikipedia.org/wiki/SCI_Games SCI Studio website: *http://www.bripro.com/scistudio/ FreeSCI merge with ''ScummVM?'': *http://www.scummvm.org/faq/#2_4 1272e3b21ba19120053d6ecc7a202147df2097e2 Freeware homebrew games 0 76 2780 2492 2023-03-04T02:04:58Z Unknown user 0 /* Ports */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RAW|RAW (Another World)]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 8a0a9bb2d24814e7944b370a34d4c00b130bc350 2781 2780 2023-03-04T02:05:17Z Unknown user 0 /* Ports */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RAW|RAW (Another World)]] *[[REminiscence]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] de68e1aef0dc285b1134d2362fb9928769c932e7 2782 2781 2023-03-04T02:05:37Z Unknown user 0 /* Ports */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heart of the Alien]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RAW|RAW (Another World)]] *[[REminiscence]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[RAW|Another World]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 727825ce76e7feed02d62740cce768e41c33a93f Emulators on Dreamcast 0 108 2783 2748 2023-03-04T02:05:53Z Unknown user 0 /* Interpreters */ wikitext text/x-wiki This is a preliminary list of all emulators and interpreters available for the Dreamcast. A cleaner, more organized list is coming soon. ==Video Game systems== ===Atari 800=== *[[Atari800DC]] ===Atari Jaguar=== *[[Project Tempest]] *[[DCJaguar]] *[[Virtual Jaguar DC]] ===Atari 2600=== *[[(D)cs2600]] *[[Stella DC]] ===Atari 7800=== *[[DC7800]] ===Colecovision=== *[[(D)Colem]] *[[CrabEmu]] ===Magnovox Odyssey=== *[[Odd-DC]] ===Mattel Intellivision=== *[[IntelliMESS]] ===Milton Bradley Vectrex=== *[[Vectrex MESS]] ===NEC TurboGrafx-16/PC Engine=== *[[PCECast]] *[[Dream Engine]] *[[HuCast]] ===Nintendo 64=== *[[DCNin64]] *[[DaedalusDC]] *[[Project64]] *[[Mupen64 DC]] ===Nintendo NES/Famicom=== *[[NesterDC SE]] *[[NesterDC]] *[[FrNES]] *[[TuxNES-DC]] *[[gleam!]] *[[DarcDC]] *[[FCE Ultra DC]] *[[CrabEmu]] ===Nintendo SNES/Super Famicom=== *[[Super Famicast]] *[[DreamSNES]] *[[Ngine SNES9x]] *[[Sintendo]] *[[Snes9x DC]] *[[SNES4All]] ===Sega Genesis/Mega Drive=== *[[Genesis Plus DC]] *[[DCGenerator]] *[[ljsdcgen]] *[[Sega Smash Pack Volume 1]] ===Sega Master System=== *[[CrabEmu]] *[[SMS Plus DC]] *[[SMEG]] *[[SMS Plus]] *[[DreamSMS]] *[[SMS+SDL\DC]] *[[DarcDC]] ===Sega Saturn=== *[[Yabause]] ===Sega SG-1000/SC-3000=== *[[CrabEmu]] *[[SMS Plus DC]] *[[Dream-O-Rama]] *[[DarcDC]] ===SNK NeoGeo=== *[[MDCNG]] *[[AES4All]] ===SNK NeoGeo CD=== *[[NeoCD/SDL DC]] *[[NeoDC]] *[[NEO4All]] *[[DREAMNEOCD]] ===Sony PlayStation=== *[[DreamPSX]] *[[PCSX-DC]] *[[PCSX Revolution]] *[[PCSX WIP]] *[[bleemcast!]] ===VTech CreatiVision=== *[[FunnyMu]] ==Arcade systems== ===Multiple Arcade Machine Emulators=== *[[Maim]] *[[MamedDC]] *[[MameDC]] *[[MAME4All]] *[[Cpmame]] *[[WowMAME]] ===Midway Z80=== *[[LaserDC]] ===NeoGeo MVS=== *[[MDCNG]] *[[AES4All]] ===Sega System 16=== *[[System16]] ===Single-game Emulators=== *[[Single-game MAME releases]] *[[DreamPac]] (Pacman) *[[DCPhoenix]] (Phoenix & Pleiads) *[[Phoenix]] *[[DCSI]] (Space Invaders) *[[SIemu]] (Space Invaders) ==Portable systems== ===Atari Lynx=== *[[HandyDC]] *[[LynxMESS]] ===Bandai WonderSwan=== *[[OswanDC]] ===Bandai WonderSwan Color=== *[[PillerkoDC]] *[[OswanDC]] ===Gameking=== *[[DreamKing]] *[[GameKengu DC]] ===Nintendo DS=== *[[NintenDS]] *[[DreamDS]] *[[DualScast]] *[[DeSmuME DC]] *[[DeSmuME for Dreamcast]] *[[DeSmuME Demo]] *[[NDS4ALL]] ===Nintendo Game Boy Advance=== *[[Visual Troy Advance]] *[[gpSPDC]] *[[NintenDS]] *[[DreamDS]] *[[DualScast]] ===Nintendo Game Boy (Color)=== *[[Boob!boy]] *[[DreamBoyColor]] *[[Gnuboy/DC]] ===Pokemon Mini=== *[[PokeMini Dream]] ===Sega Dreamcast VMU=== *[[VMoo]] *[[SoftVMS for DC]] *[[Dream Explorer]] ===Sega Game Gear=== *[[SMS Plus DC]] *[[SMS Plus]] *[[DreamSMS]] *[[DarcDC]] *[[CrabEmu]] *[[SMEG]] ===SNK NeoGeo Pocket Color=== *[[NeoPocott DC]] *[[NeoPop]] *[[RACE!DC]] ===Watara Supervision=== *[[SuperDCision]] ==Computer systems== ===Sharp MZ-Series=== *[[MZemuDC]] ===386/DOS=== *[[Bhole]] *[[DosBoxDC]] ===Amstrad CPC=== *[[CPCast]] *[[DreamCPC]] ===Amiga 500=== *[[UAE4All]] ===Apple II=== *[[Apple II Soul Captor]] *[[DCider]] ===Atari 800=== *[[Atari800DC]] ===Atari ST=== *[[DCaSTaway]] ===BBC Micro=== *[[BeebemDC]] *[[DreamBBC]] *[[VMSX2]] ===Commodore 64=== *[[DC64]] *[[DreamFrodo]] *[[Panera 64]] ===CHIP-8=== *[[Whack-a-Mole]] *[[CrabEmu]] ===Dragon 32/64=== *[[DragonDC]] ===MicroBee=== *[[NanoWasp]] ===Microsoft MSX=== *[[fMSX DC]] *[[BlueMSX]] *[[MSXCast]] *[[Dream MSX]] *[[uMSX]] *[[MadriSX DC]] ===Microsoft MSX2=== *[[UltraMSX2 DC]] *[[BlueMSX]] ===NEC PC-9801=== *[[Neko Project II]] ===Sinclair Spectrum=== *[[DC Speccyal K]] *[[DreamSpec]] *[[Spectrum 128k]] *[[ZX-Ishspectrum]] *[[ZX4ALL]] ===Thomson TO 7 and TO 8=== *[[TODC]] ==Interpreters== *[[DOSBOXDC]] *[[DreamZZT]] *[[FreeSCI]] (Sierra Adventures) *[[FrotzDC]] *[[MilkDC]] *[[onscripter]] *[[SarienDC]] *[[ScummVM]] (Lucas Arts Adventures) 66bec12bdb8c84ebb7b84b6f7de15596bb443db0 SarienDC 0 1042 2784 2245 2023-03-04T02:07:17Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=SarienDC| image=[[File:Sarien.gif|240px| Sarien for DC]]| homepage=[http://www.ganksoft.com/products/product.asp?prod_id=sariendc Homepage]| version=1.1| downloads=[http://www.ganksoft.com/redir.asp?target=sdcif Plainfiles]<br/>[http://www.ganksoft.com/redir.asp?target=sdcdj DiscJuggler]<br/>[http://www.ganksoft.com/redir.asp?target=sdcne Nero]<br/>[http://www.ganksoft.com/redir.asp?target=sdcsc Source]| release date=03/06/2002| author=[http://www.ganksoft.com/ Ganksoft]| original=[http://sarien.sourceforge.net/ Sarien]| systems=Sierra & <br/>Homebrew<br/>AGI Adventure| NTSCVGAPAL=NTSC/VGA/PAL| firstversion=''Unknown| best=No,<br/>[[ScummVM]]| isactive=No| }} ==History== Sarien is a Sierra AGI resource interpreter engine that enables you to play early Sierra On-Line(tm) AGI version 2 and version 3 games, as well as AGI games written by other people. Sarien is covered by the Free Software Foundation's GNU Public License and is an open source development. Up to date information and anonymous CVS is available at http://sarien.sourceforge.net/. Please note that Ganksoft Entertainment has only created a port of Sarien to the Dreamcast. Please see the above link for more information on the base Sarien project. Sarien can play the following games (see the included "sarien.cfg" file for additional information). ===Supported Games=== * Black Cauldron (2.00) * Kings Quest 1 (2.0F) * Kings Quest 2 * Kings Quest 2 (2.2) * Kings Quest 3 (1.01) * Kings Quest 3 (2.00) * Kings Quest 3 (2.14) * Kings Quest 3 (2.14) * Leisure Suit Larry 1 (1.00) * Mixed Up Mother Goose * Mixed Up Mother Goose * Police Quest 1 (2.0A) * Police Quest 1 (2.0G) * Police Quest 1 (2.0G) * Space Quest 1 (1.0X) * Space Quest 1 (1.1A) * Space Quest 1 (2.2) * Space Quest 2 * Space Quest 2 (2.0A) * Space Quest 2 (2.0C) * Space Quest 2 (2.0F) * XMAS Card 1986 * Demo 1 * Demo 2 * Demo 3 * Demo 4 * Demo 5 * Kings Quest 4 (v2.0) * Kings Quest 4 (v2.2) * Black Cauldron * Black Cauldron * Kings Quest 4 demo * Manhunter New York (1.22) * Manhunter San Francisco (3.02) * Gold Rush (5.25) * Gold Rush (3.5) * Gold Rush (Cracked) (3.5) * Gold Rush (Cracked) (5.25) * Donald Duck's Playground ==Downloads== * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcif Plainfiles] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcdj DiscJuggler] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcne Nero] - 03/06/2002 * 1.1 - [http://www.ganksoft.com/redir.asp?target=sdcsc Source] - 03/06/2002 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/sariendc/sdcif10.zip Plain files] - 09/25/2001 * 1.0 - Nero: ''[https://files.dcemulation.org/software/dreamcast/emulators/sariendc/sdcnet10.zip TAO], [https://files.dcemulation.org/software/dreamcast/emulators/sariendc/sdcned10.zip DAO]'' - 09/25/2001 * 1.0 - [https://files.dcemulation.org/software/dreamcast/emulators/sariendc/sdcdj10.zip DiscJuggler] - 09/25/2001 ==Links== * AGI fanmade games [http://forums.scummvm.org/viewtopic.php?t=3255 (download links)] ''via ScummVM forums.'' 4213fe930aaab72d73959660c80c2e35e89fe7c7 LinuxDC 0 1084 2785 2296 2023-03-04T02:14:55Z Unknown user 0 wikitext text/x-wiki = About DC Linux = [[Image:DCLinux1.jpg|thumb]] [[Image:DCLinux2.jpg|thumb]] {| |- |Developer: |[http://linuxdc.sf.net/ LinuxDC] (old version--new version [http://www.m17n.org/linux-sh/dreamcast/ here]) |- |Version: |Unknown |- |Last Updated: |06/20/01 |- |Description: |Get the power of Linux on your Dreamcast without having to worry about illegal issues of running software for it as well. This version comes with Mame and Doom ports. Very slow. |- |Status: |Gui now and text based, xwindows also. |} Linux DC is a port of the powerful Linux operating system to the Dreamcast. The newest versions have a GUI and can also be used by an average user. The Linux distribution for the Dreamcast includes XMAME and a port of prBoom (Doom) and can also be used to develop new applications for Dreamcast Linux. LinuxDC includes drivers for the broadband/LAN adpter. A keyboard and a mouse are needed. = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/dclinux-010605.7z Disk Juggler] |YES |ZIP |96mb |Thanks to Adrian O'Grady at fivemouse.com |- |[ftp://ftp.m17n.org/pub/super-h/dreamcast/dreamcast-linux-010605.tar.bz2 Plain Files] |No |RAR |75mb |- |Old Version |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/Linux.rar Nero] |Yes |RAR |9.9mb |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/linuxdcdj.zip Disk Juggler] |Yes |ZIP |9.7mb |} = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.com/covers Get Covers Here!] = Burning Info = ( Check Readme File First!! ) [http://dcemulation.com/legacy/help/dclinux_guide_for_dj.htm DCLinux Burning Guide DJ] cb4a284926159463cb68eb4901d282af00e6bd10 2786 2785 2023-03-04T02:16:47Z Unknown user 0 /* Covers */ wikitext text/x-wiki = About DC Linux = [[Image:DCLinux1.jpg|thumb]] [[Image:DCLinux2.jpg|thumb]] {| |- |Developer: |[http://linuxdc.sf.net/ LinuxDC] (old version--new version [http://www.m17n.org/linux-sh/dreamcast/ here]) |- |Version: |Unknown |- |Last Updated: |06/20/01 |- |Description: |Get the power of Linux on your Dreamcast without having to worry about illegal issues of running software for it as well. This version comes with Mame and Doom ports. Very slow. |- |Status: |Gui now and text based, xwindows also. |} Linux DC is a port of the powerful Linux operating system to the Dreamcast. The newest versions have a GUI and can also be used by an average user. The Linux distribution for the Dreamcast includes XMAME and a port of prBoom (Doom) and can also be used to develop new applications for Dreamcast Linux. LinuxDC includes drivers for the broadband/LAN adpter. A keyboard and a mouse are needed. = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/dclinux-010605.7z Disk Juggler] |YES |ZIP |96mb |Thanks to Adrian O'Grady at fivemouse.com |- |[ftp://ftp.m17n.org/pub/super-h/dreamcast/dreamcast-linux-010605.tar.bz2 Plain Files] |No |RAR |75mb |- |Old Version |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/Linux.rar Nero] |Yes |RAR |9.9mb |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/linuxdcdj.zip Disk Juggler] |Yes |ZIP |9.7mb |} = Burning Info = ( Check Readme File First!! ) [http://dcemulation.com/legacy/help/dclinux_guide_for_dj.htm DCLinux Burning Guide DJ] d97897b709b68c8ae9d0ef417dfe0302c35b002f 2787 2786 2023-03-04T02:16:51Z Unknown user 0 /* Burning Info */ wikitext text/x-wiki = About DC Linux = [[Image:DCLinux1.jpg|thumb]] [[Image:DCLinux2.jpg|thumb]] {| |- |Developer: |[http://linuxdc.sf.net/ LinuxDC] (old version--new version [http://www.m17n.org/linux-sh/dreamcast/ here]) |- |Version: |Unknown |- |Last Updated: |06/20/01 |- |Description: |Get the power of Linux on your Dreamcast without having to worry about illegal issues of running software for it as well. This version comes with Mame and Doom ports. Very slow. |- |Status: |Gui now and text based, xwindows also. |} Linux DC is a port of the powerful Linux operating system to the Dreamcast. The newest versions have a GUI and can also be used by an average user. The Linux distribution for the Dreamcast includes XMAME and a port of prBoom (Doom) and can also be used to develop new applications for Dreamcast Linux. LinuxDC includes drivers for the broadband/LAN adpter. A keyboard and a mouse are needed. = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/dclinux-010605.7z Disk Juggler] |YES |ZIP |96mb |Thanks to Adrian O'Grady at fivemouse.com |- |[ftp://ftp.m17n.org/pub/super-h/dreamcast/dreamcast-linux-010605.tar.bz2 Plain Files] |No |RAR |75mb |- |Old Version |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/Linux.rar Nero] |Yes |RAR |9.9mb |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/linuxdcdj.zip Disk Juggler] |Yes |ZIP |9.7mb |} 7f956c0e1ac88d27c41229eece2b423c9ca38df4 2788 2787 2023-03-04T02:18:02Z Unknown user 0 wikitext text/x-wiki = About DC Linux = [[Image:DCLinux1.jpg|thumb]] [[Image:DCLinux2.jpg|thumb]] {| |- |Developer: |[http://linuxdc.sf.net/ LinuxDC] (old version--new version [http://www.m17n.org/linux-sh/dreamcast/ here]) |- |Version: |Unknown |- |Last Updated: |06/20/01 |- |Description: |Get the power of Linux on your Dreamcast without having to worry about illegal issues of running software for it as well. This version comes with Mame and Doom ports. Very slow. |- |Status: |Gui now and text based, xwindows also. |} Linux DC is a port of the powerful Linux operating system to the Dreamcast. The newest versions have a GUI and can also be used by an average user. The Linux distribution for the Dreamcast includes XMAME and a port of prBoom (Doom) and can also be used to develop new applications for Dreamcast Linux. LinuxDC includes drivers for the broadband/LAN adpter. A keyboard and a mouse are needed. See [https://dcevolution.sourceforge.net/docs/dclinux.html more information here] = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/dclinux-010605.7z Disk Juggler] |YES |ZIP |96mb |Thanks to Adrian O'Grady at fivemouse.com |- |[ftp://ftp.m17n.org/pub/super-h/dreamcast/dreamcast-linux-010605.tar.bz2 Plain Files] |No |RAR |75mb |- |Old Version |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/Linux.rar Nero] |Yes |RAR |9.9mb |- |[https://files.dcemulation.org/software/dreamcast/linuxdc/linuxdcdj.zip Disk Juggler] |Yes |ZIP |9.7mb |} 16becf15c552a1b077bbf5f90495412a48b32b86 DCMP3 0 1013 2789 2210 2023-03-04T02:20:44Z Unknown user 0 wikitext text/x-wiki {{Infobox_Dev_Information| name=DCMP3| image=[[File:dcmp3.jpg|250px]]| homepage=[http://www.maturion.de/dreamcast/dcmp3 Homepage]| version=1.13 beta| downloads= [https://files.dcemulation.org/software/dreamcast/media/dcmp3/dcmp3_13.zip Plain Files]| release date=09/13/01| author=[[Strat76]]| isactive=No }} DCMP3 was the first MP3-player for the Dreamcast and also one of the first applications for the Dreamcast by hobby programmers. It was developed by [[Strat76]]. '''Status:''' *Wallpaper(JPEG viewing) *ID3V2 bug fixed *Playlist creation *Playlist/.m3u file support *File browser(subdirs) *Play/Stop/Next/Prev/Shuffle *New gfx by Aeg2K, bigger fonts *Noise/bitrate/samplerate bugs fixed *Disc swapping *Screen saver. Blank screen after 3 min so you dont have to burn your TVs *Pause *Control changes: Start: Read rootdir / Shuffle On/Off in playlist mode, Y: Pause/Stop, A: Continue/Play = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = *[http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] *[[DCEmulation:IRC_Chat|Chat with others about this sofware]] *[http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] *[http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info = ( Check Readme File First!! ) #Burn all files in the zip to cdr root + your mp3 files in a "MP3" dir. JPEGs in a "JPG" dir.Make sure you have the "use folder names" option enabled when extracting the zip. The disc should have a WINCE dir, MP3 dir, JPG dir and dcmp3.exe, 1st_read.bin, cube, ip.bin in the root. #File options: Mode1, ISO level2, joliet. (I use Nero) #Boot with Utopia bootdisc, then swap to DCMP3 disc. #Use the pad to select song/m3u and press A f6e2a3a7c1dfc35df0cc05c96f411415ae3b2496 2790 2789 2023-03-04T02:20:49Z Unknown user 0 /* Covers */ wikitext text/x-wiki {{Infobox_Dev_Information| name=DCMP3| image=[[File:dcmp3.jpg|250px]]| homepage=[http://www.maturion.de/dreamcast/dcmp3 Homepage]| version=1.13 beta| downloads= [https://files.dcemulation.org/software/dreamcast/media/dcmp3/dcmp3_13.zip Plain Files]| release date=09/13/01| author=[[Strat76]]| isactive=No }} DCMP3 was the first MP3-player for the Dreamcast and also one of the first applications for the Dreamcast by hobby programmers. It was developed by [[Strat76]]. '''Status:''' *Wallpaper(JPEG viewing) *ID3V2 bug fixed *Playlist creation *Playlist/.m3u file support *File browser(subdirs) *Play/Stop/Next/Prev/Shuffle *New gfx by Aeg2K, bigger fonts *Noise/bitrate/samplerate bugs fixed *Disc swapping *Screen saver. Blank screen after 3 min so you dont have to burn your TVs *Pause *Control changes: Start: Read rootdir / Shuffle On/Off in playlist mode, Y: Pause/Stop, A: Continue/Play = More Resources = *[http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] *[[DCEmulation:IRC_Chat|Chat with others about this sofware]] *[http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] *[http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info = ( Check Readme File First!! ) #Burn all files in the zip to cdr root + your mp3 files in a "MP3" dir. JPEGs in a "JPG" dir.Make sure you have the "use folder names" option enabled when extracting the zip. The disc should have a WINCE dir, MP3 dir, JPG dir and dcmp3.exe, 1st_read.bin, cube, ip.bin in the root. #File options: Mode1, ISO level2, joliet. (I use Nero) #Boot with Utopia bootdisc, then swap to DCMP3 disc. #Use the pad to select song/m3u and press A efc14636ac02f44a73b82214f43048f06b0d4681 DCPlaya 0 1079 2791 2291 2023-03-04T02:35:10Z Unknown user 0 wikitext text/x-wiki __NOTOC__ {{Infobox_Dev_Information| name=DCPlaya| image=[[Image:dcplaya1.jpg|250px]]| homepage=[http://sashipa.ben.free.fr/dcplaya/ Homepage]| price=free| version=2.0 beta| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-2.0-beta2-files.zip V2.0 Beta 2] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-2.0-beta-files.zip V2.0 Beta] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-bin-1.2.tar.gz V1.2-stable (Plain Files)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-1.2-discjuggler.zip V1.2-stable (DiscJuggler)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-1.2-nero.zip V1.2-stable (Nero)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-1.2.sbi V1.2-stable (SBI)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcload-ip-1.0.4-dcplaya.tgz dcload-ip-1.0.4 patched] | release date=11/21/2004| author=[[Benjamin Gerard]] and<br /> [[zigziggy]] (Vincent Penne)| isactive=No }} [[Image:dcplaya2.jpg|right|250px|thumb|DCPlaya playing music]] DCPlaya is without any doubt one the best multimedia players for Sega Dreamcast. DCPlaya is more than a simple music player. It is a full [http://en.wikipedia.org/wiki/Lua_%28programming_language%29 LUA development enviroment] and nearly an operating system. Simple DCPlaya users do not need to understand everything on the DCPlaya operating system. This player is also featured on the [http://www.dreamcast-scene.com/index.php/Main/Scenedicate Scenedicate] diskmag. You can discuss about DCPlaya in the [http://dcemulation.org/phpBB/viewtopic.php?t=53370 official release thread on our forums]. ---- ===Supported Formats:=== * FLV (YouTube videos) * MP3 * Ogg-Vorbis * MOD * S3M * NSF * SID Music * SC68 * Audio CD * ...and a lot more. Please help us completing this list. ===Authors=== Benjamin Gerard * ben AT sashipa.com Vincent Penne ([[zigziggy]]) * ziggy AT sashipa.com ==Reporting Bugs== Send an email to 'dcplaya_bugs AT sashipa.com'. Do not forget to add the version number. You can find it in the RELEASE.txt file in the dcplaya CD. ==Website and discussion== '''SourceForge site''' ** http://sourceforge.net/projects/dcplaya '''Official Website:''' ** http://sashipa.ben.free.fr/dcplaya/ '''DCEmulation Forums:''' ** http://dcemulation.org/phpBB/viewtopic.php?t=53370 '''LUA (the programming language of DCPlaya) at Wikipedia:''' ** http://en.wikipedia.org/wiki/Lua_%28programming_language%29 4c75a9ec22fb412f29958a4a362e887d03478f14 2792 2791 2023-03-04T02:35:27Z Unknown user 0 wikitext text/x-wiki __NOTOC__ {{Infobox_Dev_Information| name=DCPlaya| image=[[Image:dcplaya1.jpg|250px]]| homepage=[http://sashipa.ben.free.fr/dcplaya/ Homepage]| price=free| version=2.0 beta 2| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-2.0-beta2-files.zip V2.0 Beta 2] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-2.0-beta-files.zip V2.0 Beta] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-bin-1.2.tar.gz V1.2-stable (Plain Files)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-1.2-discjuggler.zip V1.2-stable (DiscJuggler)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-1.2-nero.zip V1.2-stable (Nero)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcplaya-1.2.sbi V1.2-stable (SBI)] *[https://files.dcemulation.org/software/dreamcast/media/dcplaya/dcload-ip-1.0.4-dcplaya.tgz dcload-ip-1.0.4 patched] | release date=11/21/2004| author=[[Benjamin Gerard]] and<br /> [[zigziggy]] (Vincent Penne)| isactive=No }} [[Image:dcplaya2.jpg|right|250px|thumb|DCPlaya playing music]] DCPlaya is without any doubt one the best multimedia players for Sega Dreamcast. DCPlaya is more than a simple music player. It is a full [http://en.wikipedia.org/wiki/Lua_%28programming_language%29 LUA development enviroment] and nearly an operating system. Simple DCPlaya users do not need to understand everything on the DCPlaya operating system. This player is also featured on the [http://www.dreamcast-scene.com/index.php/Main/Scenedicate Scenedicate] diskmag. You can discuss about DCPlaya in the [http://dcemulation.org/phpBB/viewtopic.php?t=53370 official release thread on our forums]. ---- ===Supported Formats:=== * FLV (YouTube videos) * MP3 * Ogg-Vorbis * MOD * S3M * NSF * SID Music * SC68 * Audio CD * ...and a lot more. Please help us completing this list. ===Authors=== Benjamin Gerard * ben AT sashipa.com Vincent Penne ([[zigziggy]]) * ziggy AT sashipa.com ==Reporting Bugs== Send an email to 'dcplaya_bugs AT sashipa.com'. Do not forget to add the version number. You can find it in the RELEASE.txt file in the dcplaya CD. ==Website and discussion== '''SourceForge site''' ** http://sourceforge.net/projects/dcplaya '''Official Website:''' ** http://sashipa.ben.free.fr/dcplaya/ '''DCEmulation Forums:''' ** http://dcemulation.org/phpBB/viewtopic.php?t=53370 '''LUA (the programming language of DCPlaya) at Wikipedia:''' ** http://en.wikipedia.org/wiki/Lua_%28programming_language%29 935a6e19177dbcd7c606ab829a555e1920fe064b JPamp3 0 1081 2793 2293 2023-03-04T02:36:18Z Unknown user 0 wikitext text/x-wiki {| |- {{Infobox_Dev_Information| name=JPamp3| homepage=[http://website.lineone.net/%7Ejpatkinson/dreamcast/jpamp3.html Homepage]| version=1.1| downloads=[https://files.dcemulation.org/software/dreamcast/media/jpamp3/jpamp3.zip Plain Files]| release date=09/19/2001| author=Josh| isactive=Yes }} JPAMP3 allows you to play MPEG1 layer3 (MP3) files stored on a PC Hard Disk through your Dreamcast via the Broadband Adaptor. It has been tested with Bladeenc, Lame, and MusicMatch encoded files. MPEG2 and MPEG2.5 are also supported, though untested. = Burning Info = ( Check Readme File First!! ) JPAMP3 SETUP GUIDE # Extract files from Jpamp3 directory on JPAMP3 floppy disc on to hard disk. # Boot Dreamcast with JPAMP3 CD. Obtain the MAC address of the Dreamcast (6 hex numbers on screen). # Edit the runmp3.bat file. Change the MAC address and IP addresses in the file. # Edit the jpamp3.cfg file. Change the pathname to your default path. Can include drive letters eg D:\MP3 # Execute runmp3.bat. Dreamcast should auto boot. a80db921ab15a717c94a21a613342e6f782b91b9 Atari800DC 0 783 2794 2638 2023-03-04T02:44:37Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Atari800 DC| image=[[File:Atari800DC.png|300px| Atari800 DC]]| homepage=[http://www.groessler.org/a800dc/index.html Homepage]| version=0.78| downloads=Local downloads: *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78-bin.tar.gz Plain files] - 08/17/08 *0.78 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.78.tar.gz Source] - 08/17/08 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77-bin.tar.gz Plain files] - 09/18/07 *0.77 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.77.tar.gz Source] - 09/18/07 *0.75 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.75-bin.tar.gz Source] - 01/17/03 *0.75 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.75.zip Source (alt)] - 01/17/03 *0.75 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.75.tar.gz Plain files] - 01/17/03 *0.72 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/atari800dc-0.72-bin.zip Plain files] - 09/20/02 *0.7 - [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/Atari_5200.rar Plain files] | release date=08/17/08| author=[[Captain Skyhawk]]| original=[http://atari800.sourceforge.net/ Atari800]| systems=Atari 400/800/600XL/800XL/etc...| best=Yes| refreshrate=''Unknown| isactive=''Unknown| }} Atari800 is an emulator for the Atari 8-bit machines (400/800/600XL/800XL/etc.) ported to the Dreamcast by [[Captain Skyhawk]] ''(aka Christian Groessler)''. The Dreamcast version uses the [[KallistiOS]] library, and is based on Subversion repository version 560. [https://files.dcemulation.org/software/dreamcast/emulators/atari800dc/kos-svn-560-0.78-diffs.gz Diffs are available] for the customizations applied to KallistiOS. The needed BIOS ROMs can also be found at SourceForge: [http://prdownloads.sf.net/atari800/xf25.zip BIOS ROMs]. ==Links== * [http://dcemulation.org/phpBB/viewtopic.php?f=34&t=7566&st=0&sk=t&sd=a DCEmulation Forums] e6afaf9ab1e458755ff7b13c79cee35370e46a33 Delicious 0 1100 2795 2314 2023-03-04T02:53:14Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Delicious |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Delic_1.jpg|center|280px|thumb| Delicious Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://yodel.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Only}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/05/2001}}} |- style="background:#ffffff" |Author || {{{author|[[#Project Team|Below]]}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Delicious by Yodel is a demo for the Dreamcast which was released at 2001-08-05 at the Assembly demoparty in Finland. It won the console competition. [[Image:Delic_2.jpg|center|250px| Delicious Demo]] [[Image:Delic_3.jpg|center|250px| Delicious Demo]] [[Image:Delic_4.jpg|center|250px| Delicious Demo]] ===Project Team=== * Snooky (Karl-Anders Johansson) - Code * Ayla (Andreas Alptun) - Code * Voodoo (Mikael Persson) - Code * Spiff (Paul Blomdahl) - Graphics / 3D modeling * Alces (Staffan Lincoln) - 3D modeling * O.B.M (Mike Wells) - Cartoons * Eyas (Ludvig Linge) - Music Delicious is one of the best Dreamcast demos out there. ==Downloads== * Demo - [https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler] ==Links== [http://www.youtube.com/watch?v=uybHZxvGHgc Video] 72a4ba7523acb45e196a6a972920a0689a073465 2796 2795 2023-03-04T02:53:52Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Delicious |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Delic_1.jpg|center|280px|thumb| Delicious Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://yodel.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Only}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/05/2001}}} |- style="background:#ffffff" |Author || {{{author|[[#Project Team|Below]]}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Delicious by Yodel is a demo for the Dreamcast which was released at 2001-08-05 at the Assembly demoparty in Finland. It won the console competition. <gallery> Image:Delic_2.jpg|center|250px| Delicious Demo Image:Delic_3.jpg|center|250px| Delicious Demo Image:Delic_4.jpg|center|250px| Delicious Demo </gallery> ===Project Team=== * Snooky (Karl-Anders Johansson) - Code * Ayla (Andreas Alptun) - Code * Voodoo (Mikael Persson) - Code * Spiff (Paul Blomdahl) - Graphics / 3D modeling * Alces (Staffan Lincoln) - 3D modeling * O.B.M (Mike Wells) - Cartoons * Eyas (Ludvig Linge) - Music Delicious is one of the best Dreamcast demos out there. ==Downloads== * Demo - [https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler] ==Links== [http://www.youtube.com/watch?v=uybHZxvGHgc Video] 3ae0059ff39f27a02e37a6b038e3b7c5619a66cc 2797 2796 2023-03-04T02:54:03Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Delicious |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Delic_1.jpg|center|280px|thumb| Delicious Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://yodel.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Only}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/05/2001}}} |- style="background:#ffffff" |Author || {{{author|[[#Project Team|Below]]}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Delicious by Yodel is a demo for the Dreamcast which was released at 2001-08-05 at the Assembly demoparty in Finland. It won the console competition. <gallery> Image:Delic_2.jpg|center|250px| Delicious Demo Image:Delic_3.jpg|center|250px| Delicious Demo Image:Delic_4.jpg|center|250px| Delicious Demo </gallery> ===Project Team=== * Snooky (Karl-Anders Johansson) - Code * Ayla (Andreas Alptun) - Code * Voodoo (Mikael Persson) - Code * Spiff (Paul Blomdahl) - Graphics / 3D modeling * Alces (Staffan Lincoln) - 3D modeling * O.B.M (Mike Wells) - Cartoons * Eyas (Ludvig Linge) - Music Delicious is one of the best Dreamcast demos out there. ==Downloads== * Demo - [https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler] ==Links== [http://www.youtube.com/watch?v=uybHZxvGHgc Video] 16f895f53e97e0177e93f6882b04eb5b5a7a5cb1 2798 2797 2023-03-04T02:54:25Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Delicious |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Delic_1.jpg|center|280px|thumb| Delicious Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://yodel.net/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|Only}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/05/2001}}} |- style="background:#ffffff" |Author || {{{author|[[#Project Team|Below]]}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Delicious by Yodel is a demo for the Dreamcast which was released at 2001-08-05 at the Assembly demoparty in Finland. It won the console competition. <gallery> Image:Delic_2.jpg|center|250px| Image:Delic_3.jpg|center|250px| Image:Delic_4.jpg|center|250px| </gallery> ===Project Team=== * Snooky (Karl-Anders Johansson) - Code * Ayla (Andreas Alptun) - Code * Voodoo (Mikael Persson) - Code * Spiff (Paul Blomdahl) - Graphics / 3D modeling * Alces (Staffan Lincoln) - 3D modeling * O.B.M (Mike Wells) - Cartoons * Eyas (Ludvig Linge) - Music Delicious is one of the best Dreamcast demos out there. ==Downloads== * Demo - [https://files.dcemulation.org/software/dreamcast/demos/delicious/ydl_deli.zip DiscJuggler] ==Links== [http://www.youtube.com/watch?v=uybHZxvGHgc Video] 6f0db8ace34c30a0b57b02434fc31c6b87e21460 Aiming Tank 0 1116 2799 2336 2023-03-04T02:58:54Z Unknown user 0 wikitext text/x-wiki {{Infobox_Game_Information| name=Aiming Tank| image=[[Image:Aimtank_1.png|center|thumb|280px| Screenshot]]| homepage=[http://nagoya.cool.ne.jp/dcdev38/result/aimtank.html Homepage]| version=Beta 2| downloads=[https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files]| release date=05/25/2002| author=''Unknown| type=1-2 Player<br/>Strategy| refreshrate=''Unknown| isactive=No }} Aiming Tank is a 1-2 player strategy shooting game. [[Image:Aimtank_2.png|280px| Aiming Tank]] [[Image:Aimtank_3.png|280px| Aiming Tank]] Destroy your opponent's tank, before he destroys you! ==Downloads== * Beta 2 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files] - 05/25/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503.zip Plain Files] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/AimingTank.sbi SBI] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503cdi.zip DiscJuggler] - 05/05/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503nrg.zip Nero] - 05/05/2002 * Snapshot - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank_src_20020803.lzh Source] - 08/03/2002 632494af516c8282f3b806700cc6c1f5a8e46edb 2800 2799 2023-03-04T02:59:00Z Unknown user 0 wikitext text/x-wiki {{Infobox_Game_Information| name=Aiming Tank| image=[[Image:Aimtank_1.png|center|280px| Screenshot]]| homepage=[http://nagoya.cool.ne.jp/dcdev38/result/aimtank.html Homepage]| version=Beta 2| downloads=[https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files]| release date=05/25/2002| author=''Unknown| type=1-2 Player<br/>Strategy| refreshrate=''Unknown| isactive=No }} Aiming Tank is a 1-2 player strategy shooting game. [[Image:Aimtank_2.png|280px| Aiming Tank]] [[Image:Aimtank_3.png|280px| Aiming Tank]] Destroy your opponent's tank, before he destroys you! ==Downloads== * Beta 2 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files] - 05/25/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503.zip Plain Files] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/AimingTank.sbi SBI] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503cdi.zip DiscJuggler] - 05/05/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503nrg.zip Nero] - 05/05/2002 * Snapshot - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank_src_20020803.lzh Source] - 08/03/2002 beeaeb97c8b397468d12add5a6245919e87e9edb 2801 2800 2023-03-04T02:59:17Z Unknown user 0 wikitext text/x-wiki {{Infobox_Game_Information| name=Aiming Tank| image=[[Image:Aimtank_1.png|center|280px| Screenshot]]| homepage=[http://nagoya.cool.ne.jp/dcdev38/result/aimtank.html Homepage]| version=Beta 2| downloads=[https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files]| release date=05/25/2002| author=''Unknown| type=1-2 Player<br/>Strategy| refreshrate=''Unknown| isactive=No }} Aiming Tank is a 1-2 player strategy shooting game. <gallery> Image:Aimtank_2.png|280px| Aiming Tank Image:Aimtank_3.png|280px| Aiming Tank </gallery> Destroy your opponent's tank, before he destroys you! ==Downloads== * Beta 2 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files] - 05/25/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503.zip Plain Files] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/AimingTank.sbi SBI] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503cdi.zip DiscJuggler] - 05/05/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503nrg.zip Nero] - 05/05/2002 * Snapshot - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank_src_20020803.lzh Source] - 08/03/2002 9066eaf4ae7515f250b2eccf6494f3944618ecba 2802 2801 2023-03-04T02:59:24Z Unknown user 0 wikitext text/x-wiki {{Infobox_Game_Information| name=Aiming Tank| image=[[Image:Aimtank_1.png|center|280px| Screenshot]]| homepage=[http://nagoya.cool.ne.jp/dcdev38/result/aimtank.html Homepage]| version=Beta 2| downloads=[https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files]| release date=05/25/2002| author=''Unknown| type=1-2 Player<br/>Strategy| refreshrate=''Unknown| isactive=No }} Aiming Tank is a 1-2 player strategy shooting game. <gallery> Image:Aimtank_2.png|280px| Image:Aimtank_3.png|280px| </gallery> Destroy your opponent's tank, before he destroys you! ==Downloads== * Beta 2 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/aimtank0525.zip Plain Files] - 05/25/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503.zip Plain Files] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/AimingTank.sbi SBI] - 05/03/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503cdi.zip DiscJuggler] - 05/05/2002 * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank0503nrg.zip Nero] - 05/05/2002 * Snapshot - [https://files.dcemulation.org/software/dreamcast/games/aimingtank/atank_src_20020803.lzh Source] - 08/03/2002 039fc9f2411097c24a8b0948c4ab982b7901b468 3D Invaders 0 1002 2803 2192 2023-03-04T03:04:19Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://axlen.com/dc/3di/1st_read.bin.gz Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' [[Image:3di-2.jpg|220px| 3D Invaders]] [[Image:3di-3.jpg|220px| 3D Invaders]] '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [http://axlen.com/dc/3di/1st_read.bin.gz Plain Files], [http://web.archive.org/web/20060614012847/http://www.dchomebrew.org/files/plain/3di-bin.zip Alt.] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di-src.tar.gz Source], [http://www.boob.co.uk/files/3di-src.tar.gz Alt.] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] 4a43e103dab2d736252727302f01fcd67941b44a 2804 2803 2023-03-04T03:04:47Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://axlen.com/dc/3di/1st_read.bin.gz Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' <gallery> Image:3di-2.jpg|220px| Image:3di-3.jpg|220px| </gallery> '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [http://axlen.com/dc/3di/1st_read.bin.gz Plain Files], [http://web.archive.org/web/20060614012847/http://www.dchomebrew.org/files/plain/3di-bin.zip Alt.] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di-src.tar.gz Source], [http://www.boob.co.uk/files/3di-src.tar.gz Alt.] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] a93d185d9c4ecef0b62c3ed0b72744b089f29202 2808 2804 2023-03-04T03:20:46Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://axlen.com/dc/3di/1st_read.bin.gz Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' <gallery> Image:3di-2.jpg|220px| Image:3di-3.jpg|220px| </gallery> '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [http://axlen.com/dc/3di/1st_read.bin.gz Plain Files], [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Alt.] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di-src.tar.gz Source], [http://www.boob.co.uk/files/3di-src.tar.gz Alt.] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] 460feb373be6a8acc208a5bed2bf0896c43b4add 2809 2808 2023-03-04T03:21:11Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' <gallery> Image:3di-2.jpg|220px| Image:3di-3.jpg|220px| </gallery> '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [http://axlen.com/dc/3di/1st_read.bin.gz Plain Files], [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Alt.] - 05/06/2002 * Pre-Release - [http://axlen.com/dc/3di-src.tar.gz Source], [http://www.boob.co.uk/files/3di-src.tar.gz Alt.] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] bbdb643a8459fb91f7172df6d7161984761ecb88 2810 2809 2023-03-04T03:22:13Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' <gallery> Image:3di-2.jpg|220px| Image:3di-3.jpg|220px| </gallery> '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-src.tar.gz Source] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] e61dd4323e8e83be9c3b8254c668128dc31e1367 Asteroids 0 954 2805 2126 2023-03-04T03:18:34Z Unknown user 0 wikitext text/x-wiki *Developer: [http://jimbomania.com Jimbo] *Version: 0.0.7 *Last Updated: March 28, 2002 *Description: A 3D version of Asteroids for the Dreamcast. *[https://files.dcemulation.org/software/dreamcast/games/asteroids/dihbNero.zip Nero Image] *[https://files.dcemulation.org/software/dreamcast/games/asteroids/dihbDJ.zip Disc Juggler] *[https://files.dcemulation.org/software/dreamcast/games/asteroids/dcasteroids007.zip Plain Files] 565d44fd329df4d0fce00157b53efdfe7ec75dea BombermanDC 0 980 2806 2162 2023-03-04T03:19:31Z Unknown user 0 wikitext text/x-wiki BombermanDC beta https://files.dcemulation.org/software/dreamcast/games/bombermandc/bombermandc122601.zip 4d683c4b2e9efe6258cdb7d304ef924b42ba8410 Brkout 0 1364 2807 2023-03-04T03:20:01Z Unknown user 0 Created page with "https://files.dcemulation.org/software/dreamcast/games/brkout/Brkout-0.1.zip" wikitext text/x-wiki https://files.dcemulation.org/software/dreamcast/games/brkout/Brkout-0.1.zip dd9918ede3477a86269e2dc3c8bd59e63afe7588 Clonetris 0 1212 2811 2449 2023-03-04T03:24:02Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | CloneTris |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Clonetris1b.jpg|thumb|center|250px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050409141434/games.timeforplanb.net/index.php Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/clonetris/clonetris.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|02/20/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Toastman]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone<br/>''(Duh...)}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== '''''Via Toastman's Archived Site: '' 'Clonetris is a Tetris-like game for the Sega Dreamcast system. It was created as a stop-gap project while I learned some of the workings of the Dreamcast and began to grow larger than I wanted it to. ''All work on Clonetris has ceased. I don't even have a working copy of the source anymore. ''This game has been rated 'A' - Suitable for All by the [http://web.archive.org/web/20060301144555/http://dreamon.cyberdogcastle.com/dirb/ DIRB: Dreamcast Independant Rating Board] (archived link).' [[File:Clonetris2b.jpg|Left|250px| Menu Screen]] ===Features=== * In order to have background music in this release. Put a MP3 in the '' 'music' '' folder at the cd root, and rename it to ''nevski3.mp3''. ===Bugs=== * The included MP3 may have problems, but if you want to use it, try encoding it differently. ''(You can pre-test in an emulator) ==Downloads== * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/clonetris/clonetris.zip Plain Files] - 02/20/2002 * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/clonetris/Clonetris.sbi SBI] - 02/20/2002 * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/clonetris/Clone_Tetris.zip Nero] - 02/20/2002 1152db8005ae0e23cc56eb1a414fdba131bd3d99 Amanda The Witch's Apprentice 0 1179 2812 2407 2023-03-04T03:25:29Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Amanda The Witch's Apprentice |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:AmandaDC.jpg|thumb|280px| Amanda the Witch]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20060501003309/consolevision.com/members/trilinear/index.html Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/amandawitch/AmandaDC.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/08/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Amanda is an apprentice to a powerful witch named Gertrude. One day Gertrude left to gather some rare bat's wings and put Amanda in charge of the cottage. After a while Amanda noticed that Zero, the witch's black cat, had slipped out an open door. Amanda realized how angry her master would be if she lost her favorite cat, Amanda quickly grabbed her master's backup broom and followed the cat's tracks to a large cave... Gameplay based on the "infamous worm game" at '[http://web.archive.org/web/20080501211246/http://www.liquidcode.org/worm.html http://www.liquidcode.org/worm.html]'. ===Controls=== * Start - to restart level * Start+Y - quit * Stick - rotate view * RTrigger - zoom in * A - go up * X - take screenshot(if using BBA or cable) ==Downloads== * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/amandawitch/AmandaDC.zip Plain Files] - 06/08/2002 * Amanda (Windows/GL) Beta 1 - [http://web.archive.org/web/20060501003309/http://consolevision.com/members/trilinear/AmandaWin.zip Win32 Exe] * Dream Selection: [http://www.dcevolution.net/index.php?id=dream_selection__volume_1 Volume 1] 2dd65449d956112d780b4bf94893188e9ad6eb76 D.I.S.S. 0 1046 2813 2251 2023-03-04T03:29:17Z Unknown user 0 wikitext text/x-wiki {{Infobox_Dev_Information| name=D.I.S.S.| image=no image| homepage=[http://www.maturion.de/dreamcast/dragyn Homepage]| version=0.8 beta| downloads= [https://files.dcemulation.org/software/dreamcast/media/diss/diss080.zip Plain Files]<br />[https://files.dcemulation.org/software/dreamcast/media/diss/diss080dj.zip DiscJuggler]<br />[https://files.dcemulation.org/software/dreamcast/media/diss/diss080-Nero.zip Nero]| release date=05/22/01| author=[[Dragyn]]| isactive=No }} D.I.S.S. ([[Dragyn]]'s Image SlideShow) is a JPEG slideshow application by [[Dragyn]]. The latest version was released on 22th May, 2001. '''Current Features (V 0.8 beta):''' *Decoding of JPG images only *Support for 24 bit color or Grayscale *Support for images up to 5120*3840 *Automatic scaling at fixed ratios of 1:1, 1:2, 1:4, 1:8 *Automatic centering of image *Next, Previous, First, Last, Blank Screen, and Quit commands *Images read from DISS CD or seperate JPG images CD (from /images/ dir) 66b919dcde73c377c18ea463b502e2de8ec17791 DCDivX 0 1080 2814 2292 2023-03-04T03:35:12Z Unknown user 0 /* Download */ wikitext text/x-wiki = About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. = Download = {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[??? Plain Files] |No |ZIP |966kb |Beta 4 (Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip Disc Juggler] |Yes |ZIP |352kb |Beta 4 (Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] |Yes |ZIP |352kb |Beta 4 (Includes GPL Source Code) |- |Old Versions |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] |No |ZIP |926kb |Beta 1 (Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip Disc Juggler] |Yes |ZIP |288kb |Beta 1 |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] |Yes |ZIP |288kb |Beta 1 |- |[??? Plain Files] |No |ZIP |1.6mb |Alpha 3(Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip Disc Juggler] |Yes |ZIP |162kb |Alpha 3 (*Update* Fixes CD Burner Issues) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] |Yes |ZIP |161kb |Alpha 3 (*Update* Fixes CD Burner Issues) |- |Tools |- |[http://www.dcemulation.org/files/software/VirtualDub.zip VirtualDub] |No |ZIP |700kb |Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. |- |[http://www.dcemulation.org/files/software/DivX412Codec.exe DivX Codecs] |No |ZIP |1.5mb |These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. |- |[http://dcemulation.org/files/software/divxDC.vcf VDDivxDC.vcf] |No |ZIP |1.12kb |This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. |} = Need Help Encoding DivX? = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] [http://www.dcemulation.org/chat.htm Chat with others about this sofware] [http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] [http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info ( Check Readme File First!! ) = [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. e92c72b264eb2d4ea4c1ebf197f57cda6b789bc5 2815 2814 2023-03-04T03:41:12Z Unknown user 0 /* Download */ wikitext text/x-wiki = About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. = Download = *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4.zip Plain Files with Source] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip DiscJuggler] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_plain.zip Plain Files with Source] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_dj.zip DiscJuggler] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_nero.zip Nero] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_plain_b2.zip Plain Files] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_b2.zip DiscJuggler] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_b2.zip Nero] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip DiscJuggler] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip DiscJuggler] -- a3 {| |- |Format |Self-Boot |Type |Size |File Details (Need Help? [[Quick_FAQ|Click Here]]) |- |[??? Plain Files] |No |ZIP |966kb |Beta 4 (Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip Disc Juggler] |Yes |ZIP |352kb |Beta 4 (Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] |Yes |ZIP |352kb |Beta 4 (Includes GPL Source Code) |- |Old Versions |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] |No |ZIP |926kb |Beta 1 (Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip Disc Juggler] |Yes |ZIP |288kb |Beta 1 |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] |Yes |ZIP |288kb |Beta 1 |- |[??? Plain Files] |No |ZIP |1.6mb |Alpha 3(Includes GPL Source Code) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip Disc Juggler] |Yes |ZIP |162kb |Alpha 3 (*Update* Fixes CD Burner Issues) |- |[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] |Yes |ZIP |161kb |Alpha 3 (*Update* Fixes CD Burner Issues) |- |Tools |- |[http://www.dcemulation.org/files/software/VirtualDub.zip VirtualDub] |No |ZIP |700kb |Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. |- |[http://www.dcemulation.org/files/software/DivX412Codec.exe DivX Codecs] |No |ZIP |1.5mb |These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. |- |[http://dcemulation.org/files/software/divxDC.vcf VDDivxDC.vcf] |No |ZIP |1.12kb |This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. |} = Need Help Encoding DivX? = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] [http://www.dcemulation.org/chat.htm Chat with others about this sofware] [http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] [http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info ( Check Readme File First!! ) = [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. 170ba04dc4cc242e94ed1f6d87d8646025347c05 2816 2815 2023-03-04T03:44:09Z Unknown user 0 /* Download */ wikitext text/x-wiki = About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. = Download = *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4.zip Plain Files with Source] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip DiscJuggler] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_plain.zip Plain Files with Source] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_dj.zip DiscJuggler] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_nero.zip Nero] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_plain_b2.zip Plain Files] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_b2.zip DiscJuggler] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_b2.zip Nero] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip DiscJuggler] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip DiscJuggler] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/VirtualDub.zip VirtualDub (old)] **Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/DivX412Codec.exe DivX 4.12] **These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/divxDC.vcf divxDC.vcf] **This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. = Need Help Encoding DivX? = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] = Covers = All Covers for All Items have been moved to a new cover system. [http://www.dcemulation.org/covers Get Covers Here!] = More Resources = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] [http://www.dcemulation.org/chat.htm Chat with others about this sofware] [http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] [http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info ( Check Readme File First!! ) = [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. 5d572b546b08ecf9cb0a82f35248513dcb0f6449 2817 2816 2023-03-04T03:44:14Z Unknown user 0 /* Covers */ wikitext text/x-wiki = About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. = Download = *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4.zip Plain Files with Source] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip DiscJuggler] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_plain.zip Plain Files with Source] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_dj.zip DiscJuggler] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_nero.zip Nero] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_plain_b2.zip Plain Files] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_b2.zip DiscJuggler] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_b2.zip Nero] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip DiscJuggler] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip DiscJuggler] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/VirtualDub.zip VirtualDub (old)] **Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/DivX412Codec.exe DivX 4.12] **These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/divxDC.vcf divxDC.vcf] **This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. = Need Help Encoding DivX? = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] = More Resources = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Discuss this software with others] [http://www.dcemulation.org/chat.htm Chat with others about this sofware] [http://www.dcemulation.org/faq/ Check out FAQ on commonly used terms] [http://www.dcemulation.org/phpBB/viewforum.php?f=9 Get help on burning and using this software] = Burning Info ( Check Readme File First!! ) = [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. 106d70214fb82fcca458ebe5bb5318bc6ba577b1 2818 2817 2023-03-04T03:44:21Z Unknown user 0 /* More Resources */ wikitext text/x-wiki = About DCDivX = DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. = Download = *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4.zip Plain Files with Source] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip DiscJuggler] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_plain.zip Plain Files with Source] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_dj.zip DiscJuggler] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_nero.zip Nero] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_plain_b2.zip Plain Files] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_b2.zip DiscJuggler] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_b2.zip Nero] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip DiscJuggler] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip DiscJuggler] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/VirtualDub.zip VirtualDub (old)] **Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/DivX412Codec.exe DivX 4.12] **These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/divxDC.vcf divxDC.vcf] **This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. = Need Help Encoding DivX? = [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] = Burning Info ( Check Readme File First!! ) = [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. a0d008a072cfdba813c88c05ab6c127363513914 2819 2818 2023-03-04T03:44:44Z Unknown user 0 wikitext text/x-wiki =About DCDivX= DCDivX is the first complete working and full speed running DivX player, this player allows you to play your favorite DivX movies on your Dreamcast. *Developer: Marc Dukette *Version: Beta 4 *Last Updated: June 14th, 2002 Status: *ogg-vorbis audio file support(not for use with video) *VP3 video codec support *removed pratically all loading time for audio files. *cut loading time in half for video files. *Changed audio file playback to stay on list screen and keep selection in synch with current file, rather than displaying loading screen. =Download= *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4.zip Plain Files with Source] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_dj.zip DiscJuggler] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b4_nero.zip Nero] -- b4 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_plain.zip Plain Files with Source] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_dj.zip DiscJuggler] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_b3_nero.zip Nero] -- b3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_plain_b2.zip Plain Files] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_b2.zip DiscJuggler] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_b2.zip Nero] -- b2 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1.zip Plain Files] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1DJ.zip DiscJuggler] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivxb1Nero.zip Nero] -- b1 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_nero_a3.zip Nero] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/dcdivx_dj_a3.zip DiscJuggler] -- a3 *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/VirtualDub.zip VirtualDub (old)] **Use this tool to convert your movies to the correct Dreamcast DIVX format. You need the DivX Codecs below installed for it to work. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/DivX412Codec.exe DivX 4.12] **These are the PC codecs you need to install in order to convert your movies to the correct Dreamcast DivX format. *[https://files.dcemulation.org/software/dreamcast/media/dcdivx/divxDC.vcf divxDC.vcf] **This is a settings file for Virtual Dub which automatically selects the correct format and etc when converting you movies to the correct divx format. This requires the two other tools above to be used. =Need Help Encoding DivX?= [http://www.dcemulation.org/phpBB/viewforum.php?f=40 Dreamcast Homebrew Apps Forum] [http://www.moosegate.com/betaboy/dcdivx BetaBoy's DCDivX Encoding Faq] [http://www.consolevision.com/dreamcast/dcdivx ZacMc's DCDivX Tutorial] =Burning Info ( Check Readme File First!! )= [http://www.dcemulation.org/newhelp/dj3burn.php?item=DCDivX%20Beta%202&filename=dcdivx_dj_b2.zip&imagefile=dcdivx_dj_b2.cdi DCDivX Beta 2 Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=DCDivX%20Beta%202&filename=dcdivx_nero_b2.zip&imagefile=dcdivx_nero_b2.nrg DCDivX Beta 2 Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=DCDivX%20Beta%202&binfile=1st_read.bin DCDivX Beta 2 Self Boot Plain Files Tutorial] [http://www.dcemulation.org/newhelp/dj3burn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_dj_a3.zip&imagefile=dcdivx_dj_a3.cdi Dreamcast DivX Player Disk Juggler Burning Tutorial] [http://www.dcemulation.org/newhelp/neroburn.php?item=Dreamcast%20DivX%20Player&filename=dcdivx_nero_a3.zip&imagefile=dcdivx_nero_a3.nrg Dreamcast DivX Player Nero Burning Rom Burning Tutorial] [http://www.dcemulation.org/newhelp/selfboot.php?item=Dreamcast%20DivX%20Player&binfile=1st_read.bin Dreamcast DivX Player Self Boot Plain Files Tutorial] = Burning DivX Swap Disk: = Burning the DIVX DC disk with the movies on it is quite easy, just use any program, even windows xp, and just burn it as regular files. It does not matter how you burn it as long as its regular files, any mode etc will work. Consult your CD Burner Software manual if you need help on burning any files. cec85be3bd5b6b84768596bd7533858b9aa1d44b Aliens 0 1072 2820 2282 2023-03-04T03:46:38Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Aliens |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Alien-sdl.jpg|center|thumb|240px| Aliens]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/aliens/aliens-SDL_DC.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|Will Sams}}} |- style="background:#ffffff" |Type of game || {{{type|Space Invaders Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== A silly little invading aliens type game -- just an example of using SDL with the mixer library. You only get one life -- stop those aliens from landing on you! ===Requirements=== * Dreamcast keyboard ===Controls=== * <space> → Fire (3 shots available) * <right arrow> → Move right * <left arrow> → Move left * <escape> → Quit the game ==Downloads== * 1.0.2 - [https://files.dcemulation.org/software/dreamcast/games/aliens/aliens-SDL_DC.zip Plain Files] - 06/07/2003 46724c5aba99b2f8a01f6f0b8b47497eb4b01003 Another Asteroids Clone 0 1181 2821 2410 2023-03-04T03:47:28Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Another Asteroids Clone |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Another_ast.jpg|center|thumb|250px| Another Asteroid Clone]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|''Unknown}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/anotherasteroids/aster_10_BIN.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/05/2004}}} |- style="background:#ffffff" |Author || {{{author|Eytan Kaziberdov}}} |- style="background:#ffffff" |Type of game || {{{type|Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} This is an Asteriods clone from Kamjin. 1. Shoot the rocks!<br/> 2. See number 1 ===Controls=== * Analog Stick, or D-Pad controls Left and Right * Right Trigger is Thrust * Left Trigger to active super weapons * Fire is A button. * Shield is B Button * HyperSpace is X button * Start to skip Intro Screen, and restart on Game Over. * Start to pause game play. ==Downloads== * 1.0 - [https://files.dcemulation.org/software/dreamcast/games/anotherasteroids/aster_10_BIN.zip Plain Files] - 04/05/2004 * 1.0 - [https://files.dcemulation.org/software/dreamcast/games/anotherasteroids/aster_10_DJ_SB.zip DiscJuggler] - 04/05/2004 89301dda603e3a1436d53977f59b1dc453e9930c Armored Campaign 0 1182 2822 2412 2023-03-04T03:48:50Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Armored Campaign |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Armcamp_2.jpg|thumb|center|280px| Armored Campaign]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20021021091614/consolevision.com/trilinear/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/arm_camp/campaign.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/21/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|Multiplayer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> Multiplayer tank deathmatch for dreamcast. [[Image:Armcamp_1.jpg|250px| Armored Campaign]] ===Controls=== * Start - to begin game and quit game * Stick - turn / tilt cannon * RTrigger - accelerate * A - fire * Y - reset cannon to forward ===Bugs=== * yes ==Downloads== * Beta 1.2 - [https://files.dcemulation.org/software/dreamcast/games/armoredcampign/campaign.zip Plain Files] - 05/21/2002 * Beta 1.2 - [https://files.dcemulation.org/software/dreamcast/games/armoredcampign/ArmoredCampaign.sbi SBI] - 05/21/2002 * [http://www.dcevolution.net/index.php?id=sapplay SAPPlay] @ DCEvolution 361d84984395d75f2346e499ffe442cac7369db4 2823 2822 2023-03-04T03:48:59Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Armored Campaign |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Armcamp_2.jpg|thumb|center|280px| Armored Campaign]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20021021091614/consolevision.com/trilinear/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1.2}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/armoredcampign/campaign.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/21/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|Multiplayer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> Multiplayer tank deathmatch for dreamcast. [[Image:Armcamp_1.jpg|250px| Armored Campaign]] ===Controls=== * Start - to begin game and quit game * Stick - turn / tilt cannon * RTrigger - accelerate * A - fire * Y - reset cannon to forward ===Bugs=== * yes ==Downloads== * Beta 1.2 - [https://files.dcemulation.org/software/dreamcast/games/armoredcampign/campaign.zip Plain Files] - 05/21/2002 * Beta 1.2 - [https://files.dcemulation.org/software/dreamcast/games/armoredcampign/ArmoredCampaign.sbi SBI] - 05/21/2002 * [http://www.dcevolution.net/index.php?id=sapplay SAPPlay] @ DCEvolution 212ce9e40c84651fa2e19bbf70b95051e9579997 DCBlast 0 1202 2824 2436 2023-03-04T03:50:54Z Unknown user 0 wikitext text/x-wiki *Developer: EvilSporkMan *Version: 0.46 *Last Updated: Tuesday, May 21, 2002 *Description: A shoot 'em up. Submitted as an entry for the 2002 programming contest. *[https://files.dcemulation.org/software/dreamcast/games/dcblast/DCBlastbin0046.zip Plain files] *[https://files.dcemulation.org/software/dreamcast/games/dcblast/DCBlast046DJ.zip DJ image] *[https://files.dcemulation.org/software/dreamcast/games/dcblast/DCBlast046Nero.zip Nero image] 8b722f8baa1d127fc8c5e6609ad744579c28c4b6 DCFighting 0 1048 2825 2254 2023-03-04T03:53:33Z Unknown user 0 wikitext text/x-wiki *Developer: [http://jimbomania.com Jimbo] *Version: 0.3.1 *Last Updated: May 20, 2002 *Description: A 3D fighting game for the Dreamcast. *[http://www.dcemulation.org/files/software/dcfighting031.bin Binary] - 0.3.1 *[http://www.dcemulation.org/files/software/dcfg031DJ.zip Disc Juggler] - 0.3.1 *[http://www.dcemulation.org/files/software/dcfg031Nero.zip Nero Image] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfighting025.zip Plain Files] - 0.2.5 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg022.zip Plain Files] - 0.2.2 e9f5f978951013ff50792108b728caed14b54dc4 2826 2825 2023-03-04T03:54:02Z Unknown user 0 wikitext text/x-wiki *Developer: [http://jimbomania.com Jimbo] *Version: 0.3.1 *Last Updated: May 20, 2002 *Description: A 3D fighting game for the Dreamcast. *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfighting031.bin Binary] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg031DJ.zip DiscJuggler] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg031Nero.zip Nero Image] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfighting025.zip Plain Files] - 0.2.5 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg022.zip Plain Files] - 0.2.2 1b5dd776fa83ffb9db5f3aafbd53fb2c0dff6845 Freeware homebrew games 0 76 2827 2782 2023-03-04T03:54:55Z Unknown user 0 /* Games */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heart of the Alien]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RAW|RAW (Another World)]] *[[REminiscence]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] 8ceacc86bb53b1ec8a0f9e4a2ff41b139e9ae94a SmashDC 0 1043 2828 2246 2023-03-04T03:56:42Z Unknown user 0 wikitext text/x-wiki *Developer: [http://mrsiggler.boob.co.uk/ MrSiggler] *Version: 1.0 *Last Updated: Thursday, May 9, 2002 *Description: SmashTV style game. Submitted as an entry for the 2002 programming contest. *[https://files.dcemulation.org/software/dreamcast/games/smashdc/smashdc1-nero.zip Nero image] *[https://files.dcemulation.org/software/dreamcast/games/smashdc/smashdc1-dj.zip DJ image] *[https://files.dcemulation.org/software/dreamcast/games/smashdc/smashdc1-plain.zip Plain files] aa9f7109bf6addf4fb7f6685fd04119c084e6cd3 DcQuad 0 1217 2829 2454 2023-03-04T04:00:21Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | dcQuad |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:DcQuad_1.jpg|thumb|center|280px| dcQuad]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|''None}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta R5}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dcquad/dcQuad.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|03/15/2002}}} |- style="background:#ffffff" |Author || {{{author|Douglas Winslow}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone}}} |- style="background:#ffffff" |Active || {{{isactive|''No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== <br/> [[Image:DcQuad_4.jpg|250px| dcQuad]] [[Image:DcQuad_2.jpg|250px| dcQuad]] [[Image:DcQuad_3.jpg|250px| dcQuad]] '''''Quote via author:<br/> '' 'dcQuad is a damn near perfect clone of the A-Mode game play in the popular 1989 Nintendo Gameboy version of Tetris. Developed (and tirelessly play-tested) on my own free time over the course of the past year, it's a must-have title for anybody who's into the whole "falling blocks" genre.' ==Downloads== * Beta R5 - [https://files.dcemulation.org/software/dreamcast/games/dcquad/dcQuad.zip Plain Files] - 03/15/2002 * Beta R5 - [https://files.dcemulation.org/software/dreamcast/games/dcquad/dcQuad.sbi SBI] - 03/15/2002 * Beta R5 - [https://files.dcemulation.org/software/dreamcast/games/dcquad/DCquad.zip Nero] 5ae18173786a2d493ac838a85cfbc29a5a3c0937 DreamAMP 0 1365 2830 2023-03-04T04:01:57Z Unknown user 0 Created page with "*[https://files.dcemulation.org/software/dreamcast/media/dreamamp/dreamamp.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/media/dreamamp/dampDJ.zip DiscJu..." wikitext text/x-wiki *[https://files.dcemulation.org/software/dreamcast/media/dreamamp/dreamamp.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/media/dreamamp/dampDJ.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/media/dreamamp/dampnero.zip Nero] 9e933dd3bd364a1ef0d82611c2e9504279a1d887 JapAmerica 0 1104 2831 2320 2023-03-04T04:04:17Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JapAmerica |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:JapAm.jpg|thumb|center|280px| JapAmerica]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://atomicbits.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|#1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dcemulation.com/dl/dl.php3?url=files/software/Dragon.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/10/2002}}} |- style="background:#ffffff" |Author || {{{author|Dragonsimoto}}} |- style="background:#ffffff" |Type of game || {{{type|Interactive<br/> Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== A tech demo. Submitted as an entry for the 2002 programming contest. '''''Quote via Author:<br/> '' 'This is my dumb demo for the contest at Dcemulation*. ''I am proud to say this is my FIRST semi complete project for the Dreamcast or anything for that matter. ''I am still learning alot!!! ''I have been coding since 2/?/02, so you can see this is a learning process. ''I wanted to make the top 50% but I doubt I get that high :(.' ===Controls=== * D-Pad → Cube(s) rotation * Y → Alpha Blending * X → Scoll thru the Demo Textures * Start → Quit ==Downloads== * [https://files.dcemulation.org/software/dreamcast/demos/japamerica/Dragon.zip Plain Files] * [https://files.dcemulation.org/software/dreamcast/demos/japamerica/DragonNero.zip Nero] * [https://files.dcemulation.org/software/dreamcast/demos/japamerica/DragonCDI.zip DiscJuggler] 2df0c1cf3ef3aafdb4f7604772074d84c943cfe4 2832 2831 2023-03-04T04:04:39Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JapAmerica |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:JapAm.jpg|thumb|center|280px| JapAmerica]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://atomicbits.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|#1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dcemulation.com/dl/dl.php3?url=files/software/Dragon.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/10/2002}}} |- style="background:#ffffff" |Author || {{{author|Dragonsimoto}}} |- style="background:#ffffff" |Type of game || {{{type|Interactive<br/> Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} A tech demo. Submitted as an entry for the 2002 programming contest. '''''Quote via Author:<br/> '' 'This is my dumb demo for the contest at Dcemulation*. ''I am proud to say this is my FIRST semi complete project for the Dreamcast or anything for that matter. ''I am still learning alot!!! ''I have been coding since 2/?/02, so you can see this is a learning process. ''I wanted to make the top 50% but I doubt I get that high :(.' ===Controls=== * D-Pad → Cube(s) rotation * Y → Alpha Blending * X → Scoll thru the Demo Textures * Start → Quit ==Downloads== * [https://files.dcemulation.org/software/dreamcast/demos/japamerica/Dragon.zip Plain Files] * [https://files.dcemulation.org/software/dreamcast/demos/japamerica/DragonNero.zip Nero] * [https://files.dcemulation.org/software/dreamcast/demos/japamerica/DragonCDI.zip DiscJuggler] 309a6662941787d947171750834933ba4dad9ccb Barrage 0 1195 2833 2429 2023-03-04T04:05:52Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Barrage |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Barrage_1.jpg|thumb|center|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20050313143932/www.storm-studios.net/sdl/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/barrage/barrage.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/07/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Will Sams]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://lgames.sourceforge.net/index.php?project=Barrage Barrage]}}} |- style="background:#ffffff" |Type of game || {{{type|Mouse Shooter}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Barrage is a rather violent action game with the objective to kill and destroy as many targets as possible within 3 minutes. The player controls a gun that may either fire small or large grenades at soldiers, jeeps and tanks. It is a very simple gameplay though it is not that easy to get high scores. A Dreamcast mouse & keyboard are required to be able to play the game. ===Controls=== * Left Button → Fire a large grenade. * Middle Button / Ctrl + Left Button → Fire a small grenade. * Right Button → Reload gun to full 36 rounds. ==Downloads== * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/barrage/barrage.zip Plain Files] - 06/07/2003 * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/barrage/barrage_src.zip Source] - 06/07/2003 93970135f947e8e55d93dbef20bdb2b5f767d017 Blockdrop 0 1197 2834 2432 2023-03-04T04:07:10Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Blockdrop |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Blockdrop1.jpg|center|thumb|300px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|0.1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/blockdrop/blockdrop-0.1.scrambled.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[nymus]]}}} |- style="background:#ffffff" |Type of game || {{{type|Tetris Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== '''''Via ReadMe:<br /> '' "BlockDrop is a tetris-like game by me, nymus ''It is my first game on DC and my very first complete programming project of any kind. ''Due to this fact, it may have a few bugs, but the current build (which I will call 0.1) is very much playable. ''There might be a small bug when you try to rotate a block that's close to the edge of the screen, but I think it adds to the challenge." '' ==Controls== *DPAD_LEFT: move block left *DPAD_RIGHT: move block right *DPAD_DOWN: move block down (if you want to speed things up) *BUTTON_A: rotate block ==Downloads== * 0.1 - [https://files.dcemulation.org/software/dreamcast/games/blockdrop/blockdrop-0.1.scrambled.zip Plain Files] - ''Unknown release date * 0.1 - [https://files.dcemulation.org/software/dreamcast/games/blockdrop/Blockdrop.sbi SBI] - ''Unknown release date ===Author's Note=== '' "The backgrounds are from my favorite Dreamcast game: Soul Calibur <br />(All that material is (c) Namco and should be used with discretion, may not be sold for profit etc, etc,. If it is wrong to use them, please let me know)" '' fe32ac8057cc2fea49ee5ec672e8448b64a6d4d8 The Bubble Machine 0 1282 2835 2531 2023-03-04T04:08:05Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Bubble Machine |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:BubbleMachine1.jpg|center|thumb|300px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/bubblemachine/puzzbobl.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Vinic Games}}} |- style="background:#ffffff" |Type of game || {{{type|Puzzle Bobble Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Vinic Games' Puzzle Bobble clone adapted to Dreamcast Fenix by DCEmu's ''Wraggster''. [[Image:BubbleMachine2.jpg|center|320px| Title Screen]] ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/bubblemachine/puzzbobl.zip Plain Files] - ''Unknown release date'' 2b14a79347b1e76651894fbbc3eb3a45235509eb 2836 2835 2023-03-04T04:08:23Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Bubble Machine |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:BubbleMachine1.jpg|center|thumb|300px| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/bubblemachine/puzzbobl.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Vinic Games}}} |- style="background:#ffffff" |Type of game || {{{type|Puzzle Bobble Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Vinic Games' Puzzle Bobble clone adapted to Dreamcast Fenix by DCEmu's ''Wraggster''. [[Image:BubbleMachine2.jpg|center|320px| Title Screen]] ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/bubblemachine/puzzbobl.zip Plain Files] - ''Unknown release date'' ddc9e42341ecb829ef0ffcbd5dadd50f532b82c6 BurgerDC 0 880 2837 2035 2023-03-04T04:12:29Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | BurgerDC |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcevolution.sourceforge.net/index.php?id=the_sandman_volume_1 The Sandman Volume 1]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Warmtoe}}}, {{{author|Krut}}}, {{{author|DaMadFiddler}}}, <br>{{{author|MetaFox}}} |- style="background:#ffffff" |Type of game || {{{type|BurgerTime Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== ''Burger DC'' was created and programmed by [[Warmtoe]], with music by [[DaMadFiddler]], and art by [[Krut]] and [[MetaFox]]. Included on [[The Sandman Volume 1]]. ==Downloads== * ''Version 2'' - [http://dcevolution.sourceforge.net/index.php?id=the_sandman_volume_1 The Sandman Volume 1] - ''December 24, 2006'' b2ca982308838a0488d38276a61604cbeaa4cd59 2847 2837 2023-03-04T04:32:24Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | BurgerDC |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcevolution.sourceforge.net/index.php?id=the_sandman_volume_1 The Sandman Volume 1]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Warmtoe}}}, {{{author|Krut}}}, {{{author|DaMadFiddler}}}, <br>{{{author|MetaFox}}} |- style="background:#ffffff" |Type of game || {{{type|BurgerTime Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ''Burger DC'' was created and programmed by [[Warmtoe]], with music by [[DaMadFiddler]], and art by [[Krut]] and [[MetaFox]]. Included on [[The Sandman Volume 1]]. ==Downloads== * ''Version 2'' - [http://dcevolution.sourceforge.net/index.php?id=the_sandman_volume_1 The Sandman Volume 1] - ''December 24, 2006'' 34ddc937d7c62fcc7ec086acdbf8211cb87867f6 The Sandman Volume 1 0 1366 2838 2023-03-04T04:12:59Z Unknown user 0 Created page with "This is the work-in-progress version of what was going to be a pressed cover CD given away free with the first issue of the DreamOn Magazine. DCEvolution had been working on t..." wikitext text/x-wiki This is the work-in-progress version of what was going to be a pressed cover CD given away free with the first issue of the DreamOn Magazine. DCEvolution had been working on this CD from 2004 but due to unforseen circumstances the magazine and CD distribution came to an abrupt end. The WIP version of the CD contains previously unreleased versions and exclusive demos of some of the best games available from the Dreamcast independent community from the 2004 era. The menu system for the pressed CD was going to be the Sandmenu but during testing Dream Inducer created by DCGrendel was used, the WIP release of the Sandman also features Dream Inducer. 175aae16413300f922abce6b82ac8fbba8ebb7b6 2846 2838 2023-03-04T04:31:52Z Unknown user 0 wikitext text/x-wiki This is the work-in-progress version of what was going to be a pressed cover CD given away free with the first issue of the DreamOn Magazine. DCEvolution had been working on this CD from 2004 but due to unforseen circumstances the magazine and CD distribution came to an abrupt end. The WIP version of the CD contains previously unreleased versions and exclusive demos of some of the best games available from the Dreamcast independent community from the 2004 era. The menu system for the pressed CD was going to be the Sandmenu but during testing Dream Inducer created by DCGrendel was used, the WIP release of the Sandman also features Dream Inducer. *[https://files.dcemulation.org/software/dreamcast/compilations/sandman/Sandman.rar DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/compilations/sandman/Sandman.txt Readme] 548515c65b5cc1601ea1b9e3cb05f6c7798bc63b Bugs 0 1208 2839 2444 2023-03-04T04:18:09Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Bugs |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Bugs1.jpg|center|thumb|280px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/bugs/bug.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|2005}}} |- style="background:#ffffff" |Author || {{{author|[[Kamjin]]}}} |- style="background:#ffffff" |Type of game || {{{type|Space Invaders Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Kill the Bugs! [[Image:Bugs2.jpg|center|thumb|320px| Play Screen]] Dpad/Analog moves left/right and A fires.<br/> Press Y to exit back to BootMenu or DCLOAD during gameplay.<br/> MotherShip will reset the Shields.<br/> ''(Which you'll really need to do often on later levels) ===Known Bugs=== * One of the aliens decides to march in the wrong direction every few levels. * Player's ship is always on Turbo Fire (Since the Bonus code is rem'd out) * Sounds Don't always play like they should when bugs move to kamekaze mode. * Kamekaze bugs don't ever hit the player. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/bugs/bug.zip Plain Files] - ??/??/2005 9d21943a053318955805c746200fac64583de177 Catz 'n Dogz 0 1243 2840 2485 2023-03-04T04:18:58Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Catz 'n Dogz |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Catzdogz_3.jpg|thumb|center|300px| Catz 'n Dogz]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/catzndogs/catzndogs.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|William Sams}}} |- style="background:#ffffff" |Type of game || {{{type|Tic-Tac-Toe}}} |- style="background:#ffffff" |Active || {{{isactive|''No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> [[Image:Catzdogz_2.jpg|250px| Catz 'n Dogz]] [[Image:Catzdogz_1.jpg|250px| Catz 'n Dogz]] Catz n' Dogz is just a simple game of Tic Tac Toe / Naughts & Crosses. ==Downloads== * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/catzndogs/catzndogs.zip Plain Files] - ''Unknown release date * Unknown Version - [https://files.dcemulation.org/software/dreamcast/games/catzndogs/CatznDogz.sbi SBI] - ''Unknown release date 4cb7c138be21443fa086dd06ff991cc120129482 Graf Orlock's Bathunt 0 1229 2841 2469 2023-03-04T04:21:24Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Graf Orlock's Bathunt |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Graforlock.jpg|thumb|center|280px| Graf Orlock's]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.storm-studios.net/ Homepage]<br/>''(Defunct)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/graforlocksbathunt/bathunt.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[OneThirty8]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} '' 'OH NO!!! Count Orlock's vampire bats got out! Can you help him round them up? Take a stroll through the woods, and if you see a bat, catch it with the "A" button. Catch all 10 bats to win. Be careful, because if you're not ready these vampire bats will suck your precious vampire blood! Lose all your blood, and you lose the game!' '' [[Image:Bathunt.jpg|280px|Bathunting]] ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/graforlocksbathunt/bathunt.zip Plain Files] - ''Unknown release date'' * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/graforlocksbathunt/bathunt.sbi SBI] - ''Unknown release date'' * DCEvolution: [http://www.dcevolution.net/index.php?id=dchakker DCHakker] Collection 14df252bc844caf4a3b7d45116a927381d039cbb Chrysler 0 1095 2842 2309 2023-03-04T04:23:42Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Chrysler |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Chrysler_1.png|thumb|300px| Chrysler Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Fit]/<br/>[http://web.archive.org/web/20060821030947/http://bandwagon.doesntexist.com/ Bandwagon]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/chrysler/chrysler_dc.zip Plain Files]<br/>[https://files.dcemulation.org/software/dreamcast/demos/chrysler/chrysrc.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/06/2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]/<br/>Bandwagon}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Demo groups 'Fit', and 'Bandwagon', ported their open source demo 'Chrysler', which is also available for Amiga, GP32, Linux and others, to the Dreamcast. Happy watching! ==Downloads== * 1st - [https://files.dcemulation.org/software/dreamcast/demos/chrysler/chrysler_dc.zip Plain Files] - 06/06/2005 * Latest - [https://files.dcemulation.org/software/dreamcast/demos/chrysler/chrysrc.zip Source] - 04/04/2009 ==Links== * [http://www.dcevolution.net/index.php?id=chrysler DCEvolution]: Hosted DiscJuggler Image * [http://pouet.net/prod.php?which=12391 Pouet]: Demo Page db2325d2b3fa0834a6652dac178b78d5ea715d04 Convey 0 1205 2843 2440 2023-03-04T04:26:57Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Convey |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Convey1.jpg|center|thumb| Playscreen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/convey_sdl/conveysdlbin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|[[Ian Micheal]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Convey is a game written originally in BASIC for use on RISC OS computers, here it is converted to SDL for multiplatform enjoyment. Guide the blob along the conveyer belt collecting the red blobs, if you miss any you go round again. http://www.cloudsprinter.com/software/conveysdl/ ===Needed=== * Requires Dreamcast keyboard to play. ==Downloads== * [https://files.dcemulation.org/software/dreamcast/games/convey/conveysdlbin.rar Plain Files] * [https://files.dcemulation.org/software/dreamcast/games/convey/conveysdlsrc.rar Source] 42609a81ed2c0bcf01e2b317d792b4ba392a059d CloneKeen 0 881 2844 2037 2023-03-04T04:28:48Z Unknown user 0 wikitext text/x-wiki CloneKeen is an open-source clone of ID's classic DOS game Commander Keen. CloneKeen runs under many platforms including Linux & win32. There are some improvements over the original such as 2-player support. Original game data files are required. A Dreamcast port is available. *[https://files.dcemulation.org/software/dreamcast/games/clonekeen/CloneKeenDC.rar Plain Files] *[https://files.dcemulation.org/software/dreamcast/games/clonekeen/CloneKeenSrc.rar Source Code] 63b2e7b18aae0646fd7cca9e7ca7380f212d2d43 Cool Herders 0 1265 2845 2511 2023-03-04T04:29:25Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Cool Herders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Cool1.jpg|thumb|280px| Cool Herders]]}}} |- style="background:#ffffff" |Release Date || {{{release date|12/15/05}}} |- style="background:#ffffff" |Author || {{{author|HarmlessLion}}} |- style="background:#ffffff" |Type of game || {{{type|Multiplayer party}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|50/60Hz}}} |} ==History== [[Image:Cool_herders_poster_p.jpg|160px|left|thumb|text-top| Cool Herders Promo Poster]] One of the few independent Dreamcast games that were released commercialy, this title is available through [http://www.goatstore.com/info.php?id=810012 The GOAT Store]. Cool Herders was originally conceived as a quick demo game from ''Moving Target Software Design'' (now defunct), for inclusion on a demo CD being produced by [[Cryptic Allusion]] for distribution at E3 in 2002. The demo was conceived and by Binky, who did all artwork, and developed by Tursi in only three weeks. The CD itself, [[DC Tonic]], included demos from a number of groups and was generally considered a success. Cool Herders itself is a party game written for [[KallistiOS|KOS]], in which four herders armed with lightning-powered crooks attempt to round up the most rampant sheep, stealing them from others if necessary. The DC Tonic version of the game did not support powerups, although the final release of the demo did include speed and lightning power ups. The play mechanics are simple: d-pad or analog stick to move your herder, and A,B,X or Y to fire lightning. Lightning stuns sheep, destroys environment (to reveal powerups), and zaps other herders, causing them to lose sheep. Trivia: the sheep sounds in the game are loving recordings of Flossie, the prettiest sheep in the world! ==The Demos== ===Demo 1=== This game was originally created for the Dreamcast specifically for inclusion as a demo on the DC Tonic E3 Demo CD. The project was abandoned in 2003, but picked up again in late 2004 and now it has been completed for commercial release through GOAT Store Publishing. [[Image:Cool1_p.jpg|150px| Screen 1]] [[Image:Cool2_p.jpg|150px| Screen 2]] ===Demo 2=== The second demo was released on March, 31th in 2006: This download is a new demo based on the released code, and is no longer related to the old version from DC Tonic. Notes - This is a very simplified demo - it includes only the New Zealand multiplayer stages (3 in total) and 3 selectable players. [[Image:Coolscreen_p.jpg|150px| Screen 1]] [[Image:Coolscreen1_s.jpg|150px| Screen 2]] ==Downloads== * [http://www.harmlesslion.com/software/herders Demo 2] ==Links== * [http://play.harmlesslion.com/products/cool.htm Official Website] * [http://www.goatstore.com/info.php?id=810012 GOAT Store Product Page] fd5e8545d9d47dab32cb11a7979ea39e096974b6 DCPacman3D 0 1258 2848 2504 2023-03-04T04:37:39Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | PacMan 3D |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:PacMan3d_1.jpg|center|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.brianpostma.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/dcpacman3d/DCPacMan3D.zip Plain Files]<br/>[https://files.dcemulation.org/software/dreamcast/games/dcpacman3d/DCPacMan3D-src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/22/2004}}} |- style="background:#ffffff" |Author || {{{author|Brian Postma}}} |- style="background:#ffffff" |Type of game || {{{type|PacMan Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> This is the Dreamcast port of Brian Postma's Java applet PacMan 3D game. [[File:PacMan3d_2.jpg|center|thumb|320px| Play Screen]] <br/> ==Downloads== * ''Unknown version - [https://files.dcemulation.org/software/dreamcast/games/dcpacman3d/DCPacMan3D.zip Plain Files] - 05/22/2004 * ''Unknown version - [https://files.dcemulation.org/software/dreamcast/games/dcpacman3d/DCPacMan3D-src.zip Source] - 05/22/2004 7fa35c379e7e0087abff79f042ffb8179958f0a5 DC R-Tronic 0 1232 2849 2472 2023-03-04T04:38:34Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin left:1em; background:#CADCFB;" !colspan="3" | DC-RTronic |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Dc-rtronic_1.jpg|thumb|center|250px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://unrational.blogspot.com/ Blog]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/dcrtronic/dcrt_200505.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|May 20th, 2005}}} |- style="background:#ffffff" |Author || {{{author|[[Warmtoe]]}}} |- style="background:#ffffff" |Type of game || {{{type|Robotron Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br /> [[Image:Dc-rtronic_2.jpg|center|300px| Game Screen]] '''''Brief desciption via author:'''''<br /> ''DCRTronic which was the robotron clone - using the gfx from R-Tronic by Trevor Smila Storey. <br /><br />I've not done much on it, but it has had a lot of code update. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/dcrtronic/dcrt_200505.zip Plain Files] - ''05/20/05'' b57a5171f9e73b35852df55f73ffd4d0a2c99523 2850 2849 2023-03-04T04:38:50Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin left:1em; background:#CADCFB;" !colspan="3" | DC-RTronic |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Dc-rtronic_1.jpg|thumb|center|250px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://unrational.blogspot.com/ Blog]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/dcrtronic/dcrt_200505.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|May 20th, 2005}}} |- style="background:#ffffff" |Author || {{{author|[[Warmtoe]]}}} |- style="background:#ffffff" |Type of game || {{{type|Robotron Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} [[Image:Dc-rtronic_2.jpg|center|300px| Game Screen]] '''''Brief desciption via author:'''''<br /> ''DCRTronic which was the robotron clone - using the gfx from R-Tronic by Trevor Smila Storey. <br /><br />I've not done much on it, but it has had a lot of code update. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/dcrtronic/dcrt_200505.zip Plain Files] - ''05/20/05'' eb33760d8c1226a82538dbb12158a5e5672d564d DCShooter 0 1201 2851 2435 2023-03-04T04:42:13Z Unknown user 0 wikitext text/x-wiki Developer: [http://jimbomania.com/ Jimbo] Version: 0.0.5x Last Updated: March 22, 2002 Description: A first person shooter for the Dreamcast. [http://www.dcemulation.org/files/software/dihbNero.zip Nero Image] [http://www.dcemulation.org/files/software/dihbDJ.zip Disc Juggler Image] [http://www.dcemulation.org/files/software/dcshooter005x.exe Plain files] {{DCWiki:BrokenInternalLinks}} cd4da1b2135d9f013ef7e9e0e2c2d626754fa788 2852 2851 2023-03-04T04:43:13Z Unknown user 0 wikitext text/x-wiki Developer: [http://jimbomania.com/ Jimbo] Version: 0.0.5x Last Updated: March 22, 2002 Description: A first person shooter for the Dreamcast. *[http://www.dcemulation.org/files/software/dihbNero.zip Nero Image] *[http://www.dcemulation.org/files/software/dihbDJ.zip Disc Juggler Image] *[http://www.dcemulation.org/files/software/dcshooter005x.exe Plain files] *[https://files.dcemulation.org/software/dreamcast/games/dcshooter/Dcshooter.zip Nero] *[https://files.dcemulation.org/software/dreamcast/games/dcshooter/dcshooter005x.exe ???] {{DCWiki:BrokenInternalLinks}} adef327bdd136ad7ae8909b80d274905bd58d0f8 DC Text Text Revolution 0 1200 2853 2434 2023-03-04T04:44:05Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | DC Text Text Revolution |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Texttext.jpg|thumb|center|280px| Text Text]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|<i>Unknown</i>}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/texttextrevolution/DCTTR.rar Source w/<br/>Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|<i>Unknown</i>}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Type of game || {{{type|Dance Dance<br/>Revolution Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Dreamcast SDL port of Text Text Revolution. The plain files binary can be found in the''' 'cd' '''directory. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/texttextrevolution/DCTTR.rar Source w/Plain Files] - ''Unknown release date'' e689a0cda9e01a1a4c036004ad95abede6583d88 RAW 0 1016 2854 2213 2023-03-04T04:46:28Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | RAW |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Aw-dc.jpg|thumb|280px| Another World]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/raw/aw-dc_1.0.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|12/30/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|RAW}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== Another World ''(Out of this World in the United States)'' is a classic action oriented platforming game created by Eric Chahi and released by Delphine Software. Gregory Montoir created an interpeter for Another World entitled RAW. RAW was shortly after shut down at the request of Eric Chahi, but permission was given for the GP32 and Dreamcast ports to continue, and the game data was permitted to be included in these ports by Eric Chahi himself. The original versions of RAW for the Dreamcast were ported by [[MetaFox]] (Mickey McMurray). When permission to release the game data with the interpreter was obtained, the project was handed over to [[GPF]] (Troy Davis). ==Downloads== * AW/DC 1.0 - [https://files.dcemulation.org/software/dreamcast/games/raw/aw-dc_1.0.zip Plainfiles] - 12/30/2005 ==Links== * [http://gpf.dcemu.co.uk/ Troy Davis (GPF) Site] * [http://web.archive.org/web/20070124142934/cyxdown.free.fr/raw/ RAW Interpreter Site ''(Archived)] c95c2f8e0839e5bdf615c6185572fb9f1d66e5d3 2855 2854 2023-03-04T04:47:49Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | RAW |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Aw-dc.jpg|thumb|280px| Another World]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/raw/aw-dc_1.0.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|12/30/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|RAW}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Another World ''(Out of this World in the United States)'' is a classic action oriented platforming game created by Eric Chahi and released by Delphine Software. Gregory Montoir created an interpeter for Another World entitled RAW. RAW was shortly after shut down at the request of Eric Chahi, but permission was given for the GP32 and Dreamcast ports to continue, and the game data was permitted to be included in these ports by Eric Chahi himself. The original versions of RAW for the Dreamcast were ported by [[MetaFox]] (Mickey McMurray). When permission to release the game data with the interpreter was obtained, the project was handed over to [[GPF]] (Troy Davis). ==Downloads== * AW/DC 1.0 - [https://files.dcemulation.org/software/dreamcast/games/raw/aw-dc_1.0.zip Plainfiles] - 12/30/2005 ==Links== * [http://gpf.dcemu.co.uk/ Troy Davis (GPF) Site] * [http://web.archive.org/web/20070124142934/cyxdown.free.fr/raw/ RAW Interpreter Site ''(Archived)] 4c2dfabc0aded4fb3b3412e8415c78f31f99a555 MiniGolf 0 1189 2856 2419 2023-03-04T04:48:38Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | MiniGolf |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:MiniGolf1.jpg|center|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://dreamcast.dcemu.co.uk/minigolf.php Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/minigolf/minigolf.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Licantropo}}} |- style="background:#ffffff" |Type of game || {{{type|Mini Golf}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Mini Golf game for the Dreamcast. Ported to the Dreamcast by Wraggster, the original GP2X version can be found [http://www.wiki.gp2x.org/wiki/Minigolf here]. [[Image:MiniGolf2.jpg|center|thumb|320px| Play Screen]] In-Game text is in Spanish. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/minigolf/minigolf.zip Plain Files] - ''Unknown release date'' 717a1626733a003a2109454b19fb68ef90af17cb 2857 2856 2023-03-04T04:48:47Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | MiniGolf |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:MiniGolf1.jpg|center|thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://dreamcast.dcemu.co.uk/minigolf.php Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/minigolf/minigolf.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|''Unknown}}} |- style="background:#ffffff" |Author || {{{author|Licantropo}}} |- style="background:#ffffff" |Type of game || {{{type|Mini Golf}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Mini Golf game for the Dreamcast. Ported to the Dreamcast by Wraggster, the original GP2X version can be found [http://www.wiki.gp2x.org/wiki/Minigolf here]. [[Image:MiniGolf2.jpg|center|thumb|320px| Play Screen]] In-Game text is in Spanish. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/minigolf/minigolf.zip Plain Files] - ''Unknown release date'' 53101d55eb50ba8a37df8646def341d9969752cf One Day Miracle 0 1108 2858 2324 2023-03-04T04:50:15Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | One Day Miracle |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:1DayMiracle 1.jpg|thumb|320px| .fit.]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/onedaymiracle/miracle_dc.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|June, 2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The fourth demo by the Finnish demogroup 'Fit' was ported to the Dreamcast in June 2005, but also the one which got the less attention. Originally made for Linux, it was later ported to Amiga PPC, MacOS X, MS-Dos, SGI Irix, and Windows. Released in 2002, for the Assembly demoparty in Helsinki, Finland. It unfortunately only became 14th in the 64k intro compo, and that's the most interesting part. This whole demo is indeed only 64k big but uses the [[SDL]] libraries, which makes the whole packet slightly bigger. Marq, the coder and designer of One Day Miracle, mentioned that it wasn't advertised on a larger scale because he wasn't very satisfied with the port. [[Image:1DayMiracle 2.jpg|320px| Demo Screen 1]] [[Image:1DayMiracle 3.jpg|320px| Demo Screen 2]] ===Credits=== * code, design............... Marq * add. code, win port ..... Pete * music ....................... Roz * thanks ...................... Sam Lantinga, AmurWolf/SoCS ==Downloads== * Local - [https://files.dcemulation.org/software/dreamcast/demos/onedaymiracle/miracle_dc.zip Plain Files] - 06/''??''/2005 ==Links== * [http://dcevolution.sourceforge.net/index.php?id=one_day_miracle DCEvolution] hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=7196 Pouet.net] Page d70cf7da9988cf3fcbc6ff56f1b6c52b49148e7f Variance 0 1093 2859 2307 2023-03-04T04:51:53Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Variance |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Variance_1.jpg|thumb| Variance]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://haujobb.scene.org/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/variance/hjb_vpal.zip DiscJuggler] (PAL)}}} |- style="background:#ffffff" |Release Date || {{{release date|April, 2001}}} |- style="background:#ffffff" |Author || {{{author|[http://haujobb.scene.org/ haujobb]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== Variance, by the German demo group haujobb, was the first huge demo for the Dreamcast. It was released in April 2001 at the Mekka & Symposium demo-party in Fallingbostel in Northern Germany, and won the console competition right next to PlayStation & GameBoy demos. Unfortunately, this demo 'only' runs on PAL machines, and graphical glitches will appear on NTSC Dreamcasts. ===Team Credits=== * Fuzzel * Acryl * Raytrayza * Nomad * Amoc * Hellfire ==Downloads== * Dreamcast (PAL) ** Local - [https://files.dcemulation.org/software/dreamcast/demos/variance/hjb_vpal.zip CDI] - 04/''??''/2001 ==Links== * [http://dcevolution.sourceforge.net/index.php?id=variance DCEvolution] Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=2415 Pouet.net] Page * [http://haujobb.scene.org/ Haujobb] Website 5db4d2ec7c78b62fb8570b5ff9e52893b86bd7ca Heart of the Alien 0 943 2860 2108 2023-03-04T04:52:51Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heart of the Alien |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:HOTA_1.jpg|280px|thumb|Cut scene]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|None}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/heartofthealien/hota.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|02/''??''/2006}}} |- style="background:#ffffff" |Author || {{{author|[[LTK]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://hota.sourceforge.net/ Heart of the Alien Redux]}}} |- style="background:#ffffff" |Type of game || {{{type|Classic Adventure}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== ''Via ReadMe<br/> '''''What is HOTA?<br/> '' 'Heart of The Alien is the sequel for the undoubtedly the best adventure of all times, Another World. Developed back in 1994 by Interplay exclusively for the Sega CD console. This is an open-source project which aims to bring this highly-addictive game to all modern consoles and computer platforms. ''Please note, that you are required to own a copy of the game beforehand, as this release loads all game elements from the cd.' ===This Release=== It's a port to Dreamcast. ===Controls=== * Pad: Up, Down, Left, Right, * A → button jump * B → button run * Y → button object * START + X → Skips video scenes / Exits from game * START + L → Fast savestate * START + R → Fast loadstate, only press it after a saved state ==Usage== This release ONLY work with an iso (like the pc version) without music track. The iso file has to be rename to hota.iso and put in a folder called hota Here is the scheme: CD-\ hota\ hota.iso ===Lacks=== * NO mp3 audio support. * Some others. ==Downloads== * ''Unknown version'' - [https://files.dcemulation.org/software/dreamcast/games/heartofthealien/hota.zip Plain Files] - 02/''??''/2006 b50686d1189492710d3950281fca52caed4a9906 Heretic 0 1154 2861 2381 2023-03-04T04:54:47Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heretic |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Heretictitle.jpg|Thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.geocities.co.jp/Playtown/2004/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown Beta''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/dcheretic.zip Plain Files] |- style="background:#ffffff" |Release Date || {{{release date|09/09/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|''Unknown Source''}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:Here-01.jpg|240px| Heretic]] [[Image:Here-02.jpg|240px| Heretic]] ===Features=== * Support for mouse, joystick, keyboard. * Supports sound. * Support music with GUS patch. * VMU saving, with compression. ===Bugs=== * Intermittent working sound. ==Downloads== * Unknown Beta - [https://files.dcemulation.org/software/dreamcast/games/heretic/dcheretic.zip Plain Files] - 09/09/2002 * MIDI Instruments - [http://www.i.h.kyoto-u.ac.jp/~shom/timidity/miniinst.zip Zipfile] * [http://www.doomworld.com/idgames/index.php?id=7044 Heretic 1.2 Shareware] @ Doomworld * [http://www.idsoftware.com/games/vintage/heretic/ Heretic Full Registered] @ id Software ''(purchase)'' ==Links== * [http://www.ravensoft.com/ Raven Software] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) 606d0e38751a7aa5dfe043cb48cb4400e848a121 2862 2861 2023-03-04T04:54:54Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Heretic |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Heretictitle.jpg|Thumb|300px| Title Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.geocities.co.jp/Playtown/2004/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown Beta''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/heretic/dcheretic.zip Plain Files] |- style="background:#ffffff" |Release Date || {{{release date|09/09/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|''Unknown Source''}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:Here-01.jpg|240px| Heretic]] [[Image:Here-02.jpg|240px| Heretic]] ===Features=== * Support for mouse, joystick, keyboard. * Supports sound. * Support music with GUS patch. * VMU saving, with compression. ===Bugs=== * Intermittent working sound. ==Downloads== * Unknown Beta - [https://files.dcemulation.org/software/dreamcast/games/heretic/dcheretic.zip Plain Files] - 09/09/2002 * MIDI Instruments - [http://www.i.h.kyoto-u.ac.jp/~shom/timidity/miniinst.zip Zipfile] * [http://www.doomworld.com/idgames/index.php?id=7044 Heretic 1.2 Shareware] @ Doomworld * [http://www.idsoftware.com/games/vintage/heretic/ Heretic Full Registered] @ id Software ''(purchase)'' ==Links== * [http://www.ravensoft.com/ Raven Software] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) 8a418ff90f14848a88e76b3e01e856cc0f8ebd16 Hexen 0 1157 2863 2384 2023-03-04T04:55:29Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hexen |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Hexen01.jpg|Thumb|300px| Main Menu]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.geocities.co.jp/Playtown/2004/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown Beta''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/hexen/dchexen.zip Plain Files] |- style="background:#ffffff" |Release Date || {{{release date|07/12/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Bero]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://www.libsdl.org/projects/hexen/ Hexen SDL]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Yes}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:Hexen02.jpg|240px| Title Screen]] ===Features=== * Support for mouse, joystick, keyboard. * Supports sound. * Support music with GUS patch. * VMU saving, with compression. ===Bugs=== * Intermittent working sound. ==Downloads== * Unknown Beta - [https://files.dcemulation.org/software/dreamcast/games/hexen/dchexen.zip Plain Files] - 07/12/2002 * MIDI Instrument Package - [http://www.i.h.kyoto-u.ac.jp/~shom/timidity/miniinst.zip Zipfile] * [http://www.doomworld.com/idgames/index.php?id=7045 Hexen 1.1 Shareware] @ Doomworld * [http://www.idsoftware.com/games/vintage/hexen/ Hexen Full Registered] @ id Software ''(purchase)'' ==Links== * [http://www.ravensoft.com/ Raven Software] * [http://sourceforge.net/projects/sdl-dc/ SDL for Dreamcast] (by Bero) f71b2031a9f9f4d33c9efbaf0cb65db451927c56 Dodgin' Diamond 2 0 1224 2864 2464 2023-03-04T04:56:48Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Dodgin' Diamond 2 |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:dodgin diamond 2_1.jpg|thumb|250px| Game Screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.screamcast.net/html/game_dodgindiamond2.htm Quzar] ''(now defunct)''<br/>/[http://ltk.dciberia.net/dreamcast/dreamcast.htm LTK] ''(now defunct)''}}} |- style="background:#ffffff" |Latest Version || {{{version|0.2.1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/dodgindiamond2/dd2_quzar.zip Plain Files]<br/>/[https://files.dcemulation.org/software/dreamcast/games/dodgindiamond2/dd2_src_quzar.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|January 25th, 2006}}} |- style="background:#ffffff" |Author || {{{author|[[Quzar]]<br/>/[[LTK]]}}} |- style="background:#ffffff" |Type of game || {{{type|Shmup}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== There were two separate, unrelated, ports of this game to the Dreamcast. One was ported by LTK, itself based off of the GP2X port by 'A600'. The Quzar version is generally considered to be superior, and was based off of the PC version. ===Quzar version=== A space shooter created by Juan J Martinez, ported to Dreamcast by Quzar. JJM's own description of the game: "This is a little shot'em up [sic] arcade game for one or two players. It aims to be an 'old school' arcade game with low resolution graphics, top-down scroll action, energy based gameplay and different weapons with several levels of power." [[File:dodgin diamond 2_2.jpg|300px| Game Screen]] ====Progress/Version==== The newest Dreamcast port includes multiplayer and high score support! This updated port was an entry into the 2005 Dream On contest (Tier 4). As of this writing, Juan's latest update of the game is '0.2.1' ==Links== * [http://www.usebox.net/jjm/dd2/ Official Dodgin' Diamond 2 page] ==Downloads== * ''Quzar (0.2.1)'' - [https://files.dcemulation.org/software/dreamcast/games/dodgindiamond2/dd2_quzar.zip Plain Files] - ''01/25/2006'' * ''Quzar (0.2.1)'' - [https://files.dcemulation.org/software/dreamcast/games/dodgindiamond2/dd2_src_quzar.zip Source] - ''01/25/2006'' * ''LTK (unknown)'' - [https://files.dcemulation.org/software/dreamcast/games/dodgindiamond2/dd2_ltk.zip Plain Files] - ''09/20/2005'' 688fbea7311afa1e3d1fe181c1a0ab0304c1783c 3D Invaders 0 1002 2865 2810 2023-03-04T04:58:11Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' <gallery> Image:3di-2.jpg|220px| Image:3di-3.jpg|220px| </gallery> '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-src.tar.gz Source] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [https://dcevolution.sourceforge.net/index.php?id=dream_selection_volume_1 Volume 1] e3899bbc6292ee106d3b112f9e7948007e50db98 2890 2865 2023-03-04T05:32:31Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Invaders |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3di-1.png|thumb|250px| 3D Invaders]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.axlen.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Pre-Release''}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Axlen]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ''Quote '''via''' [[Axlen]], the developer of 3D Invaders:'' <br /><br /> '' 'Here is a "get the feel" of play pre-release version of 3D Invaders. This is the game I'm working on for submission to the DCEmu Programming Contest. There is no scoring and only one level. No menu, and no background music yet. I've included the source for completeness, but It's built against the current KOS-CVS with the local addition of a yet to be commited NURBS library.' '' <gallery> Image:3di-2.jpg|220px| Image:3di-3.jpg|220px| </gallery> '' 'Thanks to Dr. Zoidberg for making the DiskJuggler and Nero images.' '' ==Downloads== * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-bin.zip Plain Files] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3di-src.tar.gz Source] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersDJ.zip DiscJuggler] - 05/06/2002 * Pre-Release - [https://files.dcemulation.org/software/dreamcast/games/3dinvaders/3DInvadersNero.zip Nero] - 05/06/2002 * Dream Selection: [https://dcevolution.sourceforge.net/index.php?id=dream_selection_volume_1 Volume 1] *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] 290d958dab61781e84f5cc5dc7c55c371e226762 Amanda The Witch's Apprentice 0 1179 2866 2812 2023-03-04T04:58:19Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Amanda The Witch's Apprentice |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:AmandaDC.jpg|thumb|280px| Amanda the Witch]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20060501003309/consolevision.com/members/trilinear/index.html Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/amandawitch/AmandaDC.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/08/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|''Unknown}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} Amanda is an apprentice to a powerful witch named Gertrude. One day Gertrude left to gather some rare bat's wings and put Amanda in charge of the cottage. After a while Amanda noticed that Zero, the witch's black cat, had slipped out an open door. Amanda realized how angry her master would be if she lost her favorite cat, Amanda quickly grabbed her master's backup broom and followed the cat's tracks to a large cave... Gameplay based on the "infamous worm game" at '[http://web.archive.org/web/20080501211246/http://www.liquidcode.org/worm.html http://www.liquidcode.org/worm.html]'. ===Controls=== * Start - to restart level * Start+Y - quit * Stick - rotate view * RTrigger - zoom in * A - go up * X - take screenshot(if using BBA or cable) ==Downloads== * Beta 1 - [https://files.dcemulation.org/software/dreamcast/games/amandawitch/AmandaDC.zip Plain Files] - 06/08/2002 * Amanda (Windows/GL) Beta 1 - [http://web.archive.org/web/20060501003309/http://consolevision.com/members/trilinear/AmandaWin.zip Win32 Exe] * Dream Selection: [https://dcevolution.sourceforge.net/index.php?id=dream_selection_volume_1 Volume 1] ea1f54ba647e6b6ca153e61b0fe757c547e01f55 Echo's Quest 0 1279 2867 2528 2023-03-04T04:58:26Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Echo's Quest |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Echo_1.jpg|thumb|center|250px| Echo's Quest]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20021021091614/consolevision.com/trilinear/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/echo_quest/Echos_Quest.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/21/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|Platformer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== [[Image:Echo_4.jpg|250px| Echo's Quest]] [[Image:Echo_2.jpg|250px| Echo's Quest]] [[Image:Echo_3.jpg|250px| Echo's Quest]] '' 'Echo's platforming adventure last seen on the GBA and TG16 comes to the DC in full 2.5d glory.' ===Controls=== * Start - to begin game and enter menu(without quitting) * Start+Y - quit * Stick - Tilt overworld view * RTrigger - zoom in * A - jump/select menu item(to quit) * B - exit menu(without quitting) * X - take screenshot(if using BBA or cable) * pad - move Overworld: * Completed levels are blue, incomplete levels are red, levels not yet built are gray. Game: * To complete a level, find the goal Menu: * Unlock/Relock Overworld - unlocking the overworld allows you to move past levels you have not completed * See your top score (L/R to select level) * Quit - quit game [[Image:Echo_6.jpg|250px| Echo's Quest]] [[Image:Echo_5.jpg|250px| Echo's Quest]] ==Downloads== * Beta 1.0 - [http://dcemulation.org/1-newsdump/games-demos/echo_quest/Echos_Quest.zip Plain Files] - 05/21/2002 * Beta 1.0 - [http://dcemulation.org/1-newsdump/games-demos/echo_quest/EchosQuest.sbi SBI] - 05/21/2002 * Dream Selection: [https://dcevolution.sourceforge.net/index.php?id=dream_selection_volume_1 Volume 1] 367eef3fc16d8cc301c35c47d6d8072c1b29485e 2868 2867 2023-03-04T04:59:22Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Echo's Quest |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Echo_1.jpg|thumb|center|250px| Echo's Quest]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20021021091614/consolevision.com/trilinear/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|Beta 1.0}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/echosquest/Echos_Quest.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|05/21/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Trilinear]]}}} |- style="background:#ffffff" |Type of game || {{{type|Platformer}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== [[Image:Echo_4.jpg|250px| Echo's Quest]] [[Image:Echo_2.jpg|250px| Echo's Quest]] [[Image:Echo_3.jpg|250px| Echo's Quest]] '' 'Echo's platforming adventure last seen on the GBA and TG16 comes to the DC in full 2.5d glory.' ===Controls=== * Start - to begin game and enter menu(without quitting) * Start+Y - quit * Stick - Tilt overworld view * RTrigger - zoom in * A - jump/select menu item(to quit) * B - exit menu(without quitting) * X - take screenshot(if using BBA or cable) * pad - move Overworld: * Completed levels are blue, incomplete levels are red, levels not yet built are gray. Game: * To complete a level, find the goal Menu: * Unlock/Relock Overworld - unlocking the overworld allows you to move past levels you have not completed * See your top score (L/R to select level) * Quit - quit game [[Image:Echo_6.jpg|250px| Echo's Quest]] [[Image:Echo_5.jpg|250px| Echo's Quest]] ==Downloads== * Beta 1.0 - [https://files.dcemulation.org/software/dreamcast/games/echosquest/Echos_Quest.zip Plain Files] - 05/21/2002 * Beta 1.0 - [https://files.dcemulation.org/software/dreamcast/games/echosquest/EchosQuest.sbi SBI] - 05/21/2002 * Dream Selection: [https://dcevolution.sourceforge.net/index.php?id=dream_selection_volume_1 Volume 1] eafc89ee0b84f7e013167c5b4ff4453512dbbcd1 REminiscence 0 1061 2869 2268 2023-03-04T05:00:27Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | REminiscence |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Flash.jpg|thumb|280px| Flashback]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.1.8}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://dcemulation.org/1-newsdump/games-demos/flashback/REminiscence-0.1.8dc.zip Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|11/19/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://cyxdown.free.fr/reminiscence/ REminiscence]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== REminiscence is a rewrite of the engine used in the game [http://en.wikipedia.org/wiki/Flashback_(video_game) Flashback] ''(in the US subtitled 'The Quest for Identity')'' from Delphine Software. This program is designed as a cross-platform replacement for the original executable and uses the SDL library. Original version by Gregory Montoir, 'cyx@users.sourceforge.net'. [[Image:FlashBack1.jpg|300px| Game Screen]] ===Controls=== Dreamcast Controller: * D-Pad → move Conrad * Start Button → display the options * A Button → talk / use / run / shoot * X Button → Draw weapon from holster * Y Button → use the current inventory object * B Button → display the inventory ''(Support for Dreamcast Keyboard as well) ===Needed files=== ''(Place in "Data" folder) * FB_TXT.FNT * GLOBAL.ICN * GLOBAL.FIB * GLOBAL.SPC * *.OFF * *.SPR * *.MAP * *.PAL * *.ANI * *.CT * *.MBK * *.OBJ * *.PGE * *.RP * *.TBN * *.CMD * *.POL * *CINE.* If you have a version distributed by SSI, you'll have to rename some files : * LOGOSSSI.cmd → LOGOS.cmd * LOGOSSSI.pol → LOGOS.pol * MENU1SSI.map → MENU1.map * MENU1SSI.pal → MENU1.pal You will need the Amiga MOD files listed in the readme, renamed without the ".mod" extension, if you want sound during the cut scenes. * ''Example: '''mod.flashback-voyage.mod''' → '''mod.flashback-voyage''' * Windows users can use command line renaming. Navigate to the folder containing the '.mod' files, and enter the following command. '''rename *.mod *..''' ===How to Burn=== Place the game's datafiles in the directory 'Data', and the amiga mod files into the same 'Data' folder. Place the 'Data' folder, with the 1st_read.bin, into a root folder. Selfboot ''(scramble the binary)'' that folder with [[BootDreams]]. ==Downloads== * REminiscence 0.1.8 - [https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.8dc.rar Plainfiles] - 11/19/2005 * REminiscence 0.1.8 - [https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.8src.rar Source] - 07/31/2005 * REminiscence 0.1.2 - [https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.2src.rar Source] - 02/07/2005 7581f5e3a0c62a18f5182e6b4e2e42aecf80f411 2870 2869 2023-03-04T05:00:39Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | REminiscence |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Flash.jpg|thumb|280px| Flashback]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1.1.8}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.8dc.rar Plainfiles]}}} |- style="background:#ffffff" |Release Date || {{{release date|11/19/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://cyxdown.free.fr/reminiscence/ REminiscence]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== REminiscence is a rewrite of the engine used in the game [http://en.wikipedia.org/wiki/Flashback_(video_game) Flashback] ''(in the US subtitled 'The Quest for Identity')'' from Delphine Software. This program is designed as a cross-platform replacement for the original executable and uses the SDL library. Original version by Gregory Montoir, 'cyx@users.sourceforge.net'. [[Image:FlashBack1.jpg|300px| Game Screen]] ===Controls=== Dreamcast Controller: * D-Pad → move Conrad * Start Button → display the options * A Button → talk / use / run / shoot * X Button → Draw weapon from holster * Y Button → use the current inventory object * B Button → display the inventory ''(Support for Dreamcast Keyboard as well) ===Needed files=== ''(Place in "Data" folder) * FB_TXT.FNT * GLOBAL.ICN * GLOBAL.FIB * GLOBAL.SPC * *.OFF * *.SPR * *.MAP * *.PAL * *.ANI * *.CT * *.MBK * *.OBJ * *.PGE * *.RP * *.TBN * *.CMD * *.POL * *CINE.* If you have a version distributed by SSI, you'll have to rename some files : * LOGOSSSI.cmd → LOGOS.cmd * LOGOSSSI.pol → LOGOS.pol * MENU1SSI.map → MENU1.map * MENU1SSI.pal → MENU1.pal You will need the Amiga MOD files listed in the readme, renamed without the ".mod" extension, if you want sound during the cut scenes. * ''Example: '''mod.flashback-voyage.mod''' → '''mod.flashback-voyage''' * Windows users can use command line renaming. Navigate to the folder containing the '.mod' files, and enter the following command. '''rename *.mod *..''' ===How to Burn=== Place the game's datafiles in the directory 'Data', and the amiga mod files into the same 'Data' folder. Place the 'Data' folder, with the 1st_read.bin, into a root folder. Selfboot ''(scramble the binary)'' that folder with [[BootDreams]]. ==Downloads== * REminiscence 0.1.8 - [https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.8dc.rar Plainfiles] - 11/19/2005 * REminiscence 0.1.8 - [https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.8src.rar Source] - 07/31/2005 * REminiscence 0.1.2 - [https://files.dcemulation.org/software/dreamcast/games/reminiscence/REminiscence-0.1.2src.rar Source] - 02/07/2005 a4d40fead1b9b85f7f555e93d774a3c50d776b68 Epifighter 0 1119 2871 2344 2023-03-04T05:01:30Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Epifighter |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Epifighter1.jpg|thumb|center|260px| Epifighter]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/*/http://www.epifighter.fr.st/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|''Below}}} |- style="background:#ffffff" |Release Date || {{{release date|2002}}} |- style="background:#ffffff" |Author || {{{author|[http://www.epitech.eu/ Epitech]}}} |- style="background:#ffffff" |Type of game || {{{type|Fighting}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> A game developed by students of the Epitech Game Development Laboratory using the [[Iris3D]] engine. Released in 2002. [[Image:Epifighter2.jpg|thumb|center|300px| Select Screen]] ==Downloads== * Unknown version - [https://files.dcemulation.org/software/dreamcast/games/epifighter/Epifighter.zip Plain Files] - 2002 * Unknown version - [https://files.dcemulation.org/software/dreamcast/games/epifighter/Epifighter_bO.sbi SBI] - 2002 ==Links== * [http://www.epitech.net/ Official Site] * [http://www.dcevolution.net/index.php?id=epitech_cd Epitech Game Collection] @ DCEvolution fe87e746c46b1da17ca98333f5d0ce7de7b88858 2872 2871 2023-03-04T05:01:41Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Epifighter |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Epifighter1.jpg|thumb|center|260px| Epifighter]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/*/http://www.epifighter.fr.st/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|''Below}}} |- style="background:#ffffff" |Release Date || {{{release date|2002}}} |- style="background:#ffffff" |Author || {{{author|[http://www.epitech.eu/ Epitech]}}} |- style="background:#ffffff" |Type of game || {{{type|Fighting}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} A game developed by students of the Epitech Game Development Laboratory using the [[Iris3D]] engine. Released in 2002. [[Image:Epifighter2.jpg|thumb|center|300px| Select Screen]] ==Downloads== * Unknown version - [https://files.dcemulation.org/software/dreamcast/games/epifighter/Epifighter.zip Plain Files] - 2002 * Unknown version - [https://files.dcemulation.org/software/dreamcast/games/epifighter/Epifighter_bO.sbi SBI] - 2002 ==Links== * [http://www.epitech.net/ Official Site] * [http://www.dcevolution.net/index.php?id=epitech_cd Epitech Game Collection] @ DCEvolution 01005de54ddc535d359acca9dcbdf5124602a7b6 Hex Pistols 0 1102 2873 2317 2023-03-04T05:02:40Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hex Pistols |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:HexPistol_1.png|thumb|300px| Hex Pistols Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/hexpistols/hex_pistols_dc.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/06/2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== The Finnish demo group 'Fit' ported their open source demo 'Hex Pistols', which is also available for Amiga, GP32, Linux and others, to the Dreamcast. Happy watching! ==Downloads== * 1st - [https://files.dcemulation.org/software/dreamcast/demos/hexpistols/hex_pistols_dc.zip Plain Files] - 06/06/2005 * 1st - [https://files.dcemulation.org/software/dreamcast/demos/hexpistols/hex_pistols_src.zip Source] - 05/23/2005 ==Links== * [http://www.dcevolution.net/index.php?id=hex_pistols DCEvolution]: Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=17311&howmanycomments=-1 Pouet]: Demo Page f9ee24e5a36283eea7f5f4b44b8f6c42c0c04a39 2874 2873 2023-03-04T05:03:05Z Unknown user 0 /* History */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Hex Pistols |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:HexPistol_1.png|thumb|300px| Hex Pistols Demo]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.kameli.net/fit/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|1st}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/demos/hexpistols/hex_pistols_dc.zip Plain Files]<br/>[http://dcemulation.org/1-newsdump/games-demos/hex_pistols/hex_pistols_src.zip Source]}}} |- style="background:#ffffff" |Release Date || {{{release date|06/06/2005}}} |- style="background:#ffffff" |Author || {{{author|[http://www.kameli.net/fit/ Fit]}}} |- style="background:#ffffff" |Type of game || {{{type|Demo}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} The Finnish demo group 'Fit' ported their open source demo 'Hex Pistols', which is also available for Amiga, GP32, Linux and others, to the Dreamcast. Happy watching! ==Downloads== * 1st - [https://files.dcemulation.org/software/dreamcast/demos/hexpistols/hex_pistols_dc.zip Plain Files] - 06/06/2005 * 1st - [https://files.dcemulation.org/software/dreamcast/demos/hexpistols/hex_pistols_src.zip Source] - 05/23/2005 ==Links== * [http://www.dcevolution.net/index.php?id=hex_pistols DCEvolution]: Hosted DiscJuggler Image * [http://www.pouet.net/prod.php?which=17311&howmanycomments=-1 Pouet]: Demo Page 381fd89dda626c3ec7ec28f5aa18813ae60da943 JamBombs 0 1169 2875 2397 2023-03-04T05:03:54Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | JamBombs |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|''No Screenshot Available}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://web.archive.org/web/20070914053927/dcgrendel.thewaffleiron.net/ Homepage]<br/>''(Archived)}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|''Below}}} |- style="background:#ffffff" |Release Date || {{{release date|11/01/2001}}} |- style="background:#ffffff" |Author || {{{author|[[DcGrendel]]}}} |- style="background:#ffffff" |Type of game || {{{type|Minesweeper Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ''"This is intended for serial cable owners, and '''might''' lock on machines without one attached."'' ==Downloads== * Unknown version - [https://files.dcemulation.org/software/dreamcast/games/jambombs/JamBombs.zip Plain Files] - 11/01/2001 * Unknown version - [https://files.dcemulation.org/software/dreamcast/games/jambombs/Jambombs.sbi SBI] - 11/01/2001 5721fcaaf927821d1fc0ae4a0e21d4f3c869f5f5 Ghetto Pong 0 968 2876 2148 2023-03-04T05:05:24Z Unknown user 0 wikitext text/x-wiki Ghetto Pong is a pong clone by Jordan DeLong and [[Dan Potter]]. https://files.dcemulation.org/software/dreamcast/games/ghettopong/ghetto_pong_10final_binary.tar.gz 18d0b1408dc90c5dc92fefee0d3644e6fb623c07 Lady Killer 0 1188 2877 2418 2023-03-04T05:06:12Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Lady Killer |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Ladykill.png|275px|thumb| Gameplay screen]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://www.dreamcast.es/downloads.php?descarga=255 Homepage (Español)]<br />[http://translate.google.com/translate?hl=en&sl=es&u=http://www.dreamcast.es/downloads.php%3Fdescarga%3D255&ei=pE95S-n1KNGVtgfcqMy_Cg&sa=X&oi=translate&ct=result&resnum=1&ved=0CAgQ7gEwAA&prev=/search%3Fq%3Dhttp://www.dreamcast.es/downloads.php%253Fdescarga%253D255%26hl%3Den%26rls%3Dcom.microsoft:en-us English Translated (Google)]}}} |- style="background:#ffffff" |Downloads || {{{downloads|[http://www.dreamcast.es/downloads.php?descarga=255 Homepage (Account needed)]<br />[https://files.dcemulation.org/software/dreamcast/games/ladykiller/ladykill-dc.rar Local Mirror]}}} |- style="background:#ffffff" |Release Date || {{{release date|01/24/2010}}} |- style="background:#ffffff" |Author || {{{author|[[Chui]]}}} |- style="background:#ffffff" |Type of game || {{{type|Adult Arcade Remake}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} Ladykiller is a remake made from scratch by the people from the GP2x homebrew scene, and it is very faithful to the arcade game of the same name. '''''Attention! This game is for adults (+18). Play it at your own discretion. ''''' The goal is simple: Uncover the boxes, avoid the enemies, while making sure you don't drown. [[Image:Lady2.png]][[Image:Lady1.png]] Chui is responsible for the Dreamcast port of the game. Insert credits with the R button, play with the A, and B to exit. The download includes the binary files all ready to create a disc image with Bootdreams. ===Arcade=== Lady Killer's protagonist is Gonta, a funny little diver the player controls. After choosing one of the first 6 girls (8 in total), you'll have to guide Gonta with the joystick over an invisible tile-grid set over water. His only skill is diving (he can't shoot or jump), and everytime he does so a tile turns, progressively revealing more of the girls' figure. defaaa90df9ecc16c9b453761a36b702dc0bec80 The Lord of the Rings 0 1272 2878 2521 2023-03-04T05:08:05Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | The Lord of the Rings |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[File:Lotr_1.jpg|thumb|center|280px| Volume 1]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://gpf.dcemu.co.uk/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/thelordoftherings/lotrDCfull.rar Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|04/??/2005}}} |- style="background:#ffffff" |Author || {{{author|[[GPF]]}}} |- style="background:#ffffff" |Based on || {{{original|The Lord of the Rings, Vol 1<br/>by [http://www.interplay.com/ Interplay Productions]}}} |- style="background:#ffffff" |Best Available Port<br/>For this game? || {{{best|Only}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== <br/> This is a development version of The Lord of the Rings game engine which plays famous Interplays game The Lord of the Rings. [[File:Lotr_2.jpg|250px| Lord of the Rings]] [[File:Lotr_3.jpg|250px| Lord of the Rings]] [[File:Lotr_4.jpg|250px| Lord of the Rings]] ===Features=== * Requires dreamcast keyboard to play * D-pad implemented for movement and cutscenes only. ===Controls=== * Arrows → move leader * Space → main menu * Escape → exit menu, skip cartoon * O → options menu * A → attack * V → view * G → get * U → use * S → skills * M → magic * T → talk * L → select leader * C → choose * X → exit menu ==Downloads== * lotrDCfull - [https://files.dcemulation.org/software/dreamcast/games/thelordoftherings/lotrDCfull.rar Plain Files] - 04/??/2005<br/>''(requires DOS data files)'' * lotrDCdemo - [https://files.dcemulation.org/software/dreamcast/games/thelordoftherings/lotrDCdemo.rar Plain Files] - 04/??/2005<br/>''(demo files included)'' * lotrDC - [https://files.dcemulation.org/software/dreamcast/games/thelordoftherings/lord-0.6.1src.rar Source] - 04/??/2005<br/>''(requires libxml2 lib)'' 772d47ee2c1433aa1f8824cb5f2f4fd26dfe2ffd XU4 0 1239 2879 2480 2023-03-04T05:09:02Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | Ultima IV: Quest of the Avatar |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:Xu4_1.jpg|thumb|center|280px| Title]][[Image:Xu4_2.jpg|thumb|center|280px| Gameplay]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://imrtechnology.ngemu.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|''Unknown}}} |- style="background:#ffffff" |Downloads || {{{downloads|[https://files.dcemulation.org/software/dreamcast/games/ultimaiv/UltimaIV.zip Plain Files]}}} |- style="background:#ffffff" |Release Date || {{{release date|08/04/2003}}} |- style="background:#ffffff" |Author || {{{author|[[Reaper2k2]]}}} |- style="background:#ffffff" |Based on || {{{original|[http://xu4.sourceforge.net/index.php xu4]}}} |- style="background:#ffffff" |Type of game || {{{type|Role Playing}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|''Unknown}}} |} ==History== <br/> XU4 isn't a new game based on the Ultima IV story -- it is a faithful recreation of the old game, right up to the crappy graphics. If you are looking for a game with modern gameplay and graphics, this is not it -- yet. New features that improve the gameplay and keep with the spirit of the original game will be added. [[Image:Xu4_3.gif|Ultima IV]] [[Image:Xu4_4.gif|Ultima IV]] ===Features=== * Requires Dreamcast keyboard * VMU saving * VMU graphic artwork * VGA graphics pack * Stereo soundtrack ===Controls=== * A - Attack * B - Board ship / Mount horse * C - Cast (Followed by the number of the character who will do the casting, and then the letter of the spell) * D - Descend * E - Enter * F - Fire a ship's cannons (followed by the direction, broadsides only) * G - Get Chest * H - Hole up and camp (may only be used successfully with limited frequency) * I - Ignite a torch (requires torches from guilds) * J) Jimmy lock (Followed by the direction of the door) * K - Klimb (Up by default, use D to descend) * L - Locate position (Requires sextant from that pirate place) * M - Mix Reagents (Followed by the letter of a reagent, one letter per part, with no seperators. Return mixes them. If I wanted to prepare a Jinx spell with one part of black pearl, one of nightshade, and one of mandrake root, I'd type BNM and then press return. * N - New order (followed by the numbers of the characters that you want to switch) * O - Open door (followed by the direction) * P - Peer at gem (requires a gem) * Q - Quit and Save * R - Ready a weapon * S - Search (looks on the ground for unusual items) * T - Talk (You're going to want to say "name", "job", "health", and "join" to most everyone that you meet, then ask about the things that they mention, particularly the nouns.) * U - Use (Uses an item found with the search command) * V - Volume (Toggles sound) * W - Wear armor * X - Xit (Exit your horse, ship, etc and continue on foot) * Y - Yell (Yells "giddyup" or "whoa" to speed/slow your horse) * Z - Ztats (Displays status) ==Downloads== * [https://files.dcemulation.org/software/dreamcast/games/ultimaiv/UltimaIV.zip Plain Files] - 08/04/2003 * [https://files.dcemulation.org/software/dreamcast/games/ultimaiv/UltimaIV.sbi SBI] - 08/04/2003 375bc542a95f9cf58817f385df18e2d6cdf8bac8 Freeware homebrew games 0 76 2880 2827 2023-03-04T05:10:22Z Unknown user 0 /* Compilation releases */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heart of the Alien]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RAW|RAW (Another World)]] *[[REminiscence]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] *[[The Sandman Volume 1]] 0ae73b912b6e1291e0c4b2bfd6919fce5278fb7c 2881 2880 2023-03-04T05:11:28Z Unknown user 0 /* Compilation releases */ wikitext text/x-wiki =Ports= *[[Aleph One]] *[[Cave Story]] *''Doom **[[DCDoom]] **[[DoomDC]] **[[Doom for Dreamcast|Doom4DC]] **[[nxDoom]] *[[Heart of the Alien]] *[[Heretic]] *[[Hexen]] *[[Hexen II]] *''Quake **[[DCQuake]] **[[RADquake]] **[[nxMakaqu]] **[[nuQuake]] **[[QuakeDC]] *[[RAW|RAW (Another World)]] *[[REminiscence]] *[[RoTT DC|Rise of the Triad]] *''Wolfenstein 3D **[[Wolf3D DC]] **[[Wolf4SDL\DC]] **[[sdlWolf]] =Games= *[[3D Asteroids]] *[[3D Invaders]] *[[Age of the Beast]] *[[Aiming Tank]] *[[Alice Dreams]] *[[Aliens]] *[[Amanda The Witch's Apprentice]] *[[Another Asteroids Clone]] *[[AntiPong]] *[[Armored Campaign]] *[[Asteroids]] *[[AstroChaos]] *[[Barrage]] *[[Battery]] *[[Beats of Rage]] *[[Blambastic]] *[[Blockdrop]] *[[Bloop]] *[[BombermanDC]] *[[Breakout]] *[[Brkout]] *[[The Bubble Machine]] *[[BurgerDC]] *[[Bugs]] *[[Cars DC]] *[[Catz 'n Dogz]] *[[Chicken Chase]] *[[Convey|Convey SDL]] *[[CloneKeen]] *[[Clonetris]] *[[Cool Herders]] *[[Copper Swapper]] *[[Crack Attack]] *[[DCASTLE]] *[[DCBlap]] *[[DCBlast]] *[[DCCircus]] *[[DCFighting]] *[[DCNurbs]] *[[DCPacman3D]] *[[dcQuad]] *[[DC R-Tronic]] *[[DCRPG]] *[[DCShooter]] *[[DCSquares]] *[[DC Text Text Revolution]] *[[Deathchase 3D]] *[[Digimine]] *[[Divi-dead]] *[[Dodgin' Diamond 2]] *[[Dreamchess]] *[[DreamZZT]] *[[Drill]] *[[Dynamite Dreams]] *[[Echo's Quest]] *[[Efe-Cero]] *[[Epifighter]] *[[Fantasy Force]] *[[Feet of Fury]] *[[Fenix Tetris 2]] *[[REminiscence|Flashback]] *[[Freecraft]] *[[Galaga]] *[[Ghetto Pong]] *[[Giana's Return]] *[[GP Dragoon]] *[[Graf Orlock's Bathunt]] *[[Grande]] *[[Gyruss]] *[[SmashDC]] *[[HaxOr & QuaxOr]] *[[Heart of the Alien]] *[[High Cube]] *[[Inhabitants]] *[[Iris 3D Sample]] *[[JamBombs]] *[[Joggle]] *[[Jump 'n' Bump]] *[[Lady Killer]] *[[ljsdcdev]] *[[The Lord of the Rings]] *[[Lunar Lander 2K]] *[[Lupengo]] *[[MiniGolf]] *[[Othello]] *[[Pocket Volleyball DC]] *[[Rocket Racer]] *[[Titres]] *[[Shuffle]] *[[Sonic Robo Blast 2]] *[[Spiderette]] *[[XU4|Ultima IV]] =Demos= *[[A.G.E.]] *[[Chrysler]] *[[Delicious]] *[[Hex Pistols]] *[[JapAmerica]] *[[Jenny Thinks]] *[[One Day Miracle]] *[[Reverie]] *[[Sanitized]] *[[Variance]] *[[We are going to KILJU]] =Compilation releases= *[[DC Tonic]] *[[Scenedicate]] *[[The Sandman Volume 1]] *[[Dream Selection: Volume 1]] *[[Dream Selection: Volume 2 - Tetris Clone Edition]] a6d6b2bda2fad188f85d5e8d8e5af923b49d4c33 Digimine 0 1074 2882 2286 2023-03-04T05:12:41Z Unknown user 0 wikitext text/x-wiki A minesweeper clone. https://files.dcemulation.org/software/dreamcast/games/digimine/digimine_t.zip 43d151418445c9f52ea740e103417a5c2740313d High Cube 0 977 2883 2159 2023-03-04T05:13:51Z Unknown user 0 wikitext text/x-wiki *Developer: g-funkster *Version: 1 *Last Updated: May 3, 2002 *Description: A 3D puzzle game that is similar to Intelligence Qube for the Playstation. *[https://files.dcemulation.org/software/dreamcast/games/highcube/nerohigh.zip Nero Image] *[https://files.dcemulation.org/software/dreamcast/games/highcube/dischigh.zip Disc Juggler image] *[https://files.dcemulation.org/software/dreamcast/games/highcube/highp.zip Plain files] 54d854c81d3136129571e96c2bc80db89a16bd36 Wolf3D DC 0 1177 2884 2405 2023-03-04T05:17:49Z Unknown user 0 wikitext text/x-wiki *Developer: crt0 *Version: 1 *Description: A Wolfenstein 3D port to the Dreamcast. *Controls: (using controller) Up/Down/Left/Right on D-Pad moves, B is escape, A is enter, Left trigger is space, Right trigger is control. *(using keyboard) Everything is mapped to what it was in the original game, except the S3 key of the DC keyboard is the only key mapped to stab/shoot/fire etc. *You must provide the game data files in order to use the below binaries. *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/wolf3d_demo.zip Wolf3D Demo Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/wolf3d_full.zip Wolf3D Full Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/sod_demo.zip Spear of Destiny Demo Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/sod_full.zip Spear of Destiny Full Version binary] 644908b031b2ee0abc30e7e036cd2e1053641d39 2885 2884 2023-03-04T05:18:00Z Unknown user 0 wikitext text/x-wiki *Developer: crt0 *Version: 1 *Description: A Wolfenstein 3D port to the Dreamcast. *Controls: **(using controller) Up/Down/Left/Right on D-Pad moves, B is escape, A is enter, Left trigger is space, Right trigger is control. **(using keyboard) Everything is mapped to what it was in the original game, except the S3 key of the DC keyboard is the only key mapped to stab/shoot/fire etc. *You must provide the game data files in order to use the below binaries. *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/wolf3d_demo.zip Wolf3D Demo Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/wolf3d_full.zip Wolf3D Full Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/sod_demo.zip Spear of Destiny Demo Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/sod_full.zip Spear of Destiny Full Version binary] 0e8cf9cf74f23132ab598984fa240f353303e6f2 2886 2885 2023-03-04T05:19:01Z Unknown user 0 wikitext text/x-wiki *Developer: crt0 *Version: 1 *Description: A Wolfenstein 3D port to the Dreamcast. *Controls: **(using controller) Up/Down/Left/Right on D-Pad moves, B is escape, A is enter, Left trigger is space, Right trigger is control. **(using keyboard) Everything is mapped to what it was in the original game, except the S3 key of the DC keyboard is the only key mapped to stab/shoot/fire etc. *You must provide the game data files in order to use the below binaries. *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/wolf3d_demo.zip Wolf3D Demo Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/wolf3d_full.zip Wolf3D Full Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/sod_demo.zip Spear of Destiny Demo Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/sod_full.zip Spear of Destiny Full Version binary] *[https://files.dcemulation.org/software/dreamcast/games/wolf3ddc/Wolf3d-Burn-Guide.txt burnerO's Burn Guide] 917efb1dee729ea2d21d8488a3aa9ac4e560b96f GypPlay 0 1020 2887 2217 2023-03-04T05:22:14Z Unknown user 0 wikitext text/x-wiki {{Infobox_Dev_Information| name=GypPlay| image=[[Image:GypPlay3.jpg|right|250px]]| homepage=[http://gypplay.thegypsy.com/ Homepage]| version=2.0 Lik Sang Edition| downloads=[https://files.dcemulation.org/software/dreamcast/media/gypplay/GypPlay_LikSangEdition.zip Plain Files]| release date=03/05/01| author=[[TheGypsy]]| isactive=No }} __NOTOC__ GypPlay is a Dreamcast movie player by [[TheGypsy]] that allows you to play movies from a CD. The last version was released and optimized for the [[y2kode]] coding contest that was organized by [[Lik-Sang]]. == Supported Formats == *.mpg (MPEG-1 only) *.mpeg (MPEG-1 only) *.dat (MPEG-1 only) *.avi (no odd codecs!) *.m1v (MPEG-1 video, no audio) *.sfd (v1.01 SFD format works, but no audio. Newer SFDs not supported.) <gallery> Image:GypPlay1.jpg|thumb Image:GypPlay2.jpg|thumb Image:GypPlay3.jpg|thumb </gallery> ==Download== *[https://files.dcemulation.org/software/dreamcast/media/gypplay/GypPlay_LikSangEdition.zip Plain Files] *[http://www.dcemulation.orgfiles/software/DcVideoSettings.mcf DCVideoFile] **This is a TMPG video settings file. To be used with TMPGENC and sets PERFECT conversion settings when watching movies on your dreamcast. To use it press load at the bottom right in TMPG. *[http://www.dcemulation.org/files/software/TMPGEnc.zip TMPGEnc] **A tool used to convert ANY movie you have to the correct dreamcast format. *[http://www.dcemulation.org/files/software/VideoCodecs.zip Video Codecs] **A complete set of the three most used codecs on the net which include, smr, divx, mp42 and others. They include encodecs and decodecs so this adds more video support for the video conversion tools found here this is for PC only. *[http://www.dcemulation.org/files/software/mpeg2vcr.zip Mpeg2VCR] **It's a util to convert Movie files which can be a nice alternative to TMPG it also has support for SFD format. ==Links== *[http://www.boob.co.uk B00B! Dreamcast Research] *[http://www.thegypsy.com TheGypsy.com] *[http://gypplay.thegypsy.com GypPlay.TheGypsy.com] c885e97bf7f88dd9ecaf796103b38874537973e2 Titres 0 1056 2888 2262 2023-03-04T05:31:59Z Unknown user 0 wikitext text/x-wiki *Developer: [http://jimbomania.com/ Jimbo] *Version: 0.0.7 *Last Updated: Thursday, May 9, 2002 *Description: A tetris clone. *[http://www.dcemulation.org/files/software/titres007.zip Plain files] *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] 769dc55d4d8321e9cc60fe647cceec0899943851 2894 2888 2023-03-04T05:35:09Z Unknown user 0 wikitext text/x-wiki *Developer: [http://jimbomania.com/ Jimbo] *Version: 0.0.7 *Last Updated: Thursday, May 9, 2002 *Description: A tetris clone. *[https://files.dcemulation.org/software/dreamcast/games/titres/titres007.zip Plain files] *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/titres/titres-006.zip Plain files] -- version 0.0.6 2f5184a9696692e6cc326baa32e81f19b8e4fbfc 3D Asteroids 0 904 2889 2063 2023-03-04T05:32:19Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="3" | 3D Asteroids |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="3" | {{{image|[[Image:3dAsteriods2.jpg|thumb|300px| 3D Asteroids]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|[http://jimbomania.com/ Homepage]}}} |- style="background:#ffffff" |Latest Version || {{{version|0.0.7}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>None</i>}}} |- style="background:#ffffff" |Release Date || {{{release date|05/06/2002}}} |- style="background:#ffffff" |Author || {{{author|[[Jimbo]]}}} |- style="background:#ffffff" |Type of game || {{{type|3D Asteroids Clone}}} |- style="background:#ffffff" |Active || {{{isactive|No}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==History== [[Image:3dAsteriods1.jpg|230px| 3D Asteroids]] ''A 3D version of the arcade classic Asteroids.'' ==Downloads== * dcasteroids-0.0.7 - [http://web.archive.org/web/20061006052027/http://www.dchomebrew.org/zacmcd/Files/asteriods.zip Plainfiles] - 05/06/2002 * dcasteroids-0.0.7 - [http://www.boob.co.uk/files/dcasteroids-0.0.7.nrg Nero Image] - 05/06/2002 * dcasteroids-0.0.7 - [http://www.boob.co.uk/files/dcasteroids-0.0.7.elf Elf] - 05/06/2002 * dcasteroids-0.0.7 - [http://www.boob.co.uk/files/dcasteroids-0.0.7.tar.gz Source] - 05/06/2002 *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] 5b9827585a4ddd8e185466681ca4430c4d6179a2 DCFighting 0 1048 2891 2826 2023-03-04T05:32:50Z Unknown user 0 wikitext text/x-wiki *Developer: [http://jimbomania.com Jimbo] *Version: 0.3.1 *Last Updated: May 20, 2002 *Description: A 3D fighting game for the Dreamcast. *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfighting031.bin Binary] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg031DJ.zip DiscJuggler] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg031Nero.zip Nero Image] - 0.3.1 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfighting025.zip Plain Files] - 0.2.5 *[https://files.dcemulation.org/software/dreamcast/games/dcfighting/dcfg022.zip Plain Files] - 0.2.2 *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] 6c62dc302b22f897b09c8e3d688458d7f69e738b SmashDC 0 1043 2892 2828 2023-03-04T05:33:23Z Unknown user 0 wikitext text/x-wiki *Developer: [http://mrsiggler.boob.co.uk/ MrSiggler] *Version: 1.0 *Last Updated: Thursday, May 9, 2002 *Description: SmashTV style game. Submitted as an entry for the 2002 programming contest. *[https://files.dcemulation.org/software/dreamcast/games/smashdc/smashdc1-nero.zip Nero image] *[https://files.dcemulation.org/software/dreamcast/games/smashdc/smashdc1-dj.zip DJ image] *[https://files.dcemulation.org/software/dreamcast/games/smashdc/smashdc1-plain.zip Plain files] *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] 46add9b0a1d22afc84a860fc42ee2a9f828e7ffa Rocket Racer 0 1170 2893 2398 2023-03-04T05:34:05Z Unknown user 0 wikitext text/x-wiki *Developer: Trilinear *Version: Beta 2 *Description: A futuristic-styled racing game. *[https://files.dcemulation.org/software/dreamcast/games/dihbNero.zip Nero Image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/dihbDJ.zip DJ image with 3D Astroids, 3D Invaders, DCFighting, DCShooter, Rocket Racer, SmashDC, and Titres] *[https://files.dcemulation.org/software/dreamcast/games/rocketracer/rocket2.zip Plain Files] 3cc3a384877abf89adf525eef9bdae8fa3df54cf Othello 0 1047 2895 2252 2023-03-04T05:36:33Z Unknown user 0 wikitext text/x-wiki An Othello game. https://files.dcemulation.org/software/dreamcast/games/othello/Othello-DJ-img.zip 1faff6b1523e157700dc567ad6f6457e4f9c2840 Shuffle 0 1062 2896 2269 2023-03-04T05:37:54Z Unknown user 0 wikitext text/x-wiki Shuffle *[https://files.dcemulation.org/software/dreamcast/games/shuffle/Shuffle-DJ-img.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/games/shuffle/Shuffle.zip Nero image] 65b8b4c664c9753b5b6efde796070e939d3bad1c FrotzDC 0 1367 2897 2023-03-04T06:05:26Z Unknown user 0 Created page with "*[https://files.dcemulation.org/software/dreamcast/emulators/frotzdc/frotzdc-1.1-dc.zip FrotzDC 1.1 Plain files] *[https://files.dcemulation.org/software/dreamcast/emulators/f..." wikitext text/x-wiki *[https://files.dcemulation.org/software/dreamcast/emulators/frotzdc/frotzdc-1.1-dc.zip FrotzDC 1.1 Plain files] *[https://files.dcemulation.org/software/dreamcast/emulators/frotzdc/FrotzDC-1.1.zip FrotzDC 1.1 Source] *[https://files.dcemulation.org/software/dreamcast/emulators/frotzdc/libc99-3.0.tar.gz libc99] *[https://files.dcemulation.org/software/dreamcast/emulators/frotzdc/frotzdcdj.zip FrotzDC DiscJuggler] - Unknown version *[https://files.dcemulation.org/software/dreamcast/emulators/frotzdc/frotzdcnero.zip FrotzDC Nero] - Unknown Version b6807568f9eead9b8043a2e845d2af304be4f6cd Cdi4dc 0 215 2898 2249 2023-03-04T06:10:05Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=CDI4DC| image=[[File:Cdi4dc 03b img.gif|center|250px]]| homepage=[http://sbibuilder.shorturl.com/ Homepage]| version=0.3b| downloads=[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_03b.zip Binary]| release date=4/13/2007| author=[[SiZiOUS]]| }} This program was created by [[SiZiOUS]] to replace [[bin2boot]] by [[Xeal]], a tool that converts ISO images into [[selfboot|selfbooting]] DiscJuggler images. It also supports other [[selfboot formats|selfbooting formats]]. There are Linux binaries based on 0.2b [ttps://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux_colors.zip here] (colors) and [https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip here] (no colors). =Older Versions= *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_03b.zip cdi4dc v0.3b by SiZiOUS *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux_colors.zip cdi4dc v0.2b for Linux with colors by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip cdi4dc v0.2b for Linux by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b.zip v0.2b by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_01b.zip cdi4dc v0.1b by SiZiOUS] e56ce18fad9178f7fcbe1067cc766822d53b329f Cdi4dc 0 215 2899 2898 2023-03-04T06:10:12Z Unknown user 0 wikitext text/x-wiki {{Infobox_Tools_Information| name=CDI4DC| image=[[File:Cdi4dc 03b img.gif|center|250px]]| homepage=[http://sbibuilder.shorturl.com/ Homepage]| version=0.3b| downloads=[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_03b.zip Binary]| release date=4/13/2007| author=[[SiZiOUS]]| }} This program was created by [[SiZiOUS]] to replace [[bin2boot]] by [[Xeal]], a tool that converts ISO images into [[selfboot|selfbooting]] DiscJuggler images. It also supports other [[selfboot formats|selfbooting formats]]. There are Linux binaries based on 0.2b [ttps://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux_colors.zip here] (colors) and [https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip here] (no colors). =Older Versions= *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_03b.zip cdi4dc v0.3b by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux_colors.zip cdi4dc v0.2b for Linux with colors by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip cdi4dc v0.2b for Linux by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b.zip v0.2b by SiZiOUS] *[https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_01b.zip cdi4dc v0.1b by SiZiOUS] eba405d173849a9473c6f28631fd2a3e39c7c0f2 Apple II Soul Captor 0 915 2900 2754 2023-03-04T06:17:53Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=Apple II Soul Captor| image=No Image Available| homepage=Unknown| version=August, 2002| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/apple2soulecaptor/a2sc-bin-1.zip Plain Files] | release date=Unknown| author=[http://consolevision.com/members/dcgrendel/ DCGrendel]| original=N/A| systems=Apple II / II+| best=Unknown| isactive=No }} Developer: [http://consolevision.com/members/dcgrendel/ DCGrendel] <br> Updated: August, 2002 <br> <br> Emulation of the Apple II and II+ computers, with support for save states, disk images (read only), multilingual menu support (English menus distributed, third parties are welcome to translate the menu files into their home language.) <BR><BR> Speed: 100% Sound: 50% ==Downloads== *[https://files.dcemulation.org/software/dreamcast/emulators/apple2soulecaptor/a2sc-bin-1.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/apple2soulecaptor/Apple2.sbi SBIv2.1] d241664816e6682573f3b6d1cc574a035677d76f DC7800 0 787 2901 2643 2023-03-04T06:19:21Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/a7800new.rar Plain Files Ver?] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/dc7800.zip Plain Files Ver?] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/DCA7800v2_CG.sbi SBIv3.0 Ver?] | release date=Unknown| last update=16/02/04| author=Ian Micheal| original=N/A| systems=Atari 2600 / Atari 7800| best=Unknown| isactive=No }} DC7800 is a an Atari 2600/7800 emulator compiled by [[Ian MIcheal]] based on [[Warmtoe]]'s work on MESS and MAME. Its last version was v3, released on February 16, 2004. [[Category:Emulator]] 3cc4075ad9340bc60b667bf24a172f22c9ca9587 2902 2901 2023-03-04T06:20:10Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DC7800| image=No Screenshot available| homepage=Unknown| version=V3| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/a7800new.rar Plain Files Ver?] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/dc7800.zip Plain Files Ver?] *[https://files.dcemulation.org/software/dreamcast/emulators/dc7800/DCA7800v2_CG.sbi SBIv3.0 Ver?] | release date=Unknown| last update=16/02/04| author=Ian Micheal| original=N/A| systems=Atari 2600 / Atari 7800| best=Unknown| isactive=No }} DC7800 is a an Atari 2600/7800 emulator compiled by [[Ian MIcheal]] based on [[Warmtoe]]'s work on MESS and MAME. Its last version was v3, released on February 16, 2004. [https://dcemulation.org/phpBB/viewtopic.php?t=36622 Forum thread] [[Category:Emulator]] 5b5c0ea87b47ceb1f389fd1c9d2405e35163dc08 Boob!boy 0 927 2903 2738 2023-03-04T06:21:06Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Boob!boy| image=[[Image:boobboy.jpg|center|thumb|250px| Boob!boy]]| homepage=[http://www.boob.co.uk/emulators/gameboy.html Homepage]| version=1.5| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/boobboy/boobboy.zip Plain Files]| release date=12/22/2000| author=[[CyRUS64]]| original=Boob!boy| systems=Nintendo GameBoy<br />GameBoy Color| best=No| refreshrate=60Hz| isactive=No }} ==History== Boob!boy is the first Gameboy emulator for the Dreamcast by [[CyRUS64]]. Its name is inspired by the Dreamcast website B00B! Dreamcast Research, since the author, [[CyRUS64]], was the founder of B00B!. Unlike most other emulators, Boob!boy was written from scratch and is not a normal port. There also exists a PC version of Boob!boy which supports sound. ''Screenshots:<br/>[http://www.dcemulation.org/images/screens/boob_boy01.jpg Image 1], [http://www.dcemulation.org/images/screens/boob_boy02.jpg Image 2], [http://www.dcemulation.org/images/screens/boob_boy03.jpg Image 3],<br/>[http://www.dcemulation.org/images/screens/boob_boy04.jpg Image 4], [http://www.dcemulation.org/images/screens/boob_boy05.jpg Image 5], [http://www.dcemulation.org/images/screens/boob_boy06.jpg Image 6]. ===Feaures=== * Frameskip implemented - Boob!boy should now be faster with only a small amount of frameskipping noticeable. For example, Super Mario Land without doubt now runs at FULL SPEED. * Super Gameboy Support added * Fixed a memory problem that meant memory wasn't being freed up after the game was exited and hence when you had played 4/5 games the dc would run out of memory and crash. You should now be able to play as many different games as you want without having to reset the dc! * Swapped around A and B keys to make it more like a real gameboy! * New menus - a license screen is now displayed explaining that Boob!boy is not licensed or endorsed by Sega. Also a menu screen has been implemented which currently only features a play game option... (pretty pointless at the moment then!) * Made game-select screen more user-friendly by speeding up page-select and game-select movements * Fixed bug causing a delay before loading the game to be played * Implemented load from file functions saving much-needed memory... This also has resulted in a speed-up in the emulation since Video Ram can now be used for more important tasks! * Found and "zapped" other little bugs in the code, which although didn't cause any problems in current versions would have done so in the future. ===Bugs=== * Since sound caused Boob!boy to crash on the Dreamcast, it has been disabled in the Dreamcast version. ==Downloads== * 1.5 (KOS) - [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/boobboy.zip Plain Files] * 1.5 (KOS)- [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boobboy_1.5_bO.sbi SBIv3.0] * 1.5 (KOS)- [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boobboy.sbi SBIv2.1] * 1.5 beta (WINCE) - [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boob!boy.zip Plain Files], [https://files.dcemulation.org/software/dreamcast/emulators/boobboy/Boob!boy.txt Readme] 5e6a4f918d208d5795ab9dab06c3c4c806606112 Gnuboy/DC 0 928 2904 2744 2023-03-04T06:25:41Z Unknown user 0 /* Downloads */ wikitext text/x-wiki {{Infobox_Emulator_Information| name=gnuboy/DC| image=[[Image:Gnuboydc.jpg|center|250px]]| homepage=[http://dchelp.dcemulation.org/?gnuboy%2FDC Current]<br/>/[http://pqrs.org/dreamcast/software/dcgnuboy/ Old]| version=1.0.4| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104.zip Plain Files]<br/>[https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104_src.zip Source]| release date=04/06/2008| author=emptythought ''(1.0.4 ↑)''<br/>[[Takayama Fumihiko]] ''(1.0.3 ↓)''| original=[http://brightrain.aerifal.cx/~laguna/ Gnuboy]| systems=Nintendo Gameboy/<br/>Gameboy Color| refreshrate=60Hz| firstversion=''Unknown| best=Yes| isactive=Yes| }} ==History== A great port of the Gameboy Color emulator gnuboy by [[Takayama Fumihiko]], which he left at version '1.0.3-0.6'. It later received some minor updates by Fackue, with help from [[Quzar]]. It now has support for zipped roms (.zip), and slightly higher game compatibility. ===Features=== * GB/GBC emulate with sound. * smooth sound with GBC. * save support (with long filename support) * state save/load * frameskip. * screen adjustment. * added support for Zipped roms * save icon for VMU saves ===Bugs=== * ROM path display ==Downloads== * 1.0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104.zip Plain Files] - 04/06/2008 * 1.0.4 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboy_104_src.zip Source] - 04/06/2008 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/gnuboy-1.0.3-0.6.zip Plain Files] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/Gnuboy_1.0.3_bO.sbi SBIv3.0] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/Gnuboy.sbi SBIv2.1] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboyNero.zip Nero] - 08/04/2002 * 1.0.3 - [https://files.dcemulation.org/software/dreamcast/emulators/gnuboydc/dcgnuboyDJ.zip DiscJuggler] - 08/04/2002 * 1.0.3 - [ftp://ftp.pqrs.org/dc/gnuboy/source/dcgnuboy-1.0.3-0.6.tar.gz Source] - 08/04/2002 {{DCWiki:BrokenInternalLinks}} ==Links== * [http://www.dcevolution.net/index.php?id=gameboy_gameboy_color DCEvolution]: Dream Emulation Project * [http://sourceforge.net/projects/gnuboydc/ Sourceforge]: Hosted Page 19af9843343a20f6ce5b3d47ad1e192d4d76bd9c Dream Engine 0 797 2905 2653 2023-03-04T06:28:48Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=DreamEngine| image=| homepage=[http://www.billnagel.com/ Homepage]| version=V0.01| downloads=[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/dengine.zip Plain Files]| release date=Unknown| last update=07-28-02| author=Bill Nagel| original=N/A| systems=TG-16/PC Engine| best=Unknown| isactive=Unknown }}Developer: [http://www.billnagel.com/ Bill Nagel] A TG-16/PC Engine emulator. Speed varies but many games run at (or near) full speed. Currently no sound. *[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/dengine.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/DreamEngine0.01.txt Dream Engine 0.01 README file] *[https://files.dcemulation.org/software/dreamcast/emulators/dreamengine/DreamEngine.sbi DreamEngine SBIv2.1 file] [[Category:Emulator]] 3fe8ca9a7a07f14ccc23cc32e07b692b42dbd077 FrNES 0 817 2906 2667 2023-03-04T06:31:44Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=FrNES| homepage=[http://members.shaw.ca/regex/FrNES.html Homepage]| version=0.60| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-DJImage.zip DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-NeroImage.zip Nero] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60Final-RawFiles.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/Frnes.sbi SBIv2.1] | release date=12/24/2001| author=[[ReGex]]| original=pNesX<br/>(Racoon)| systems=NES| best=No.| refreshrate=50Hz / 60Hz| isactive=No }} FrNES is a good but dated open-source NES emulator for Dreamcast based on the pNesX, an NES emulator for the PlayStation One by Racoon. FrNES was released in 2001. [[NesterDC]] surpassed it. Still, it offers decent speed and features: *Vastly Improved Scrolling / PPU Engine *Partial SH4 Assembly Language Implementation *AutoFrameSkip Added (Press Left at FrameSkip == 0) *Frameskip fixed (works the way it's expected to now) *Many More Options *Font customization *Source Release *Improved Mapper Support for mappers 0-4 *Partial Mapper Support for mappers 7 and 9 *Fixed Disc Swapping *More sound improvements ==Screenshots== <gallery> Image:Frnes1.jpg|center|250px| Image:Frnes2.jpg|center|250px| Image:Frnes3.jpg|center|250px| Image:Frnes4.jpg|center|250px| </gallery> ==Older versions== *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b2-RawFiles.zip 0.60b2 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.60b-RawFiles.zip 0.60b Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-RawFiles.zip 0.50 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.50-DJImage.zip 0.50 DiscJuggler] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/frnes4pl.zip 0.40? Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-RawFiles.zip 0.05 Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/frnes/FrNES-0.05-DJImage.zip 0.05 Disc Juggler] ==Links== *[http://archives.dcemulation.org/ReGex Official Website] 5aad4f64c15a57dcfec527a0fe73c0ad87df942e Genesis Plus DC 0 839 2907 2726 2023-03-04T06:32:58Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=Genesis Plus / DC| version=07/26/2006| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/Gpdc-gpwt-26072006-BA.zip GPDC BlackAura] 07/26/06 *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/gpdcq-012007.zip GPDC Quzar] 01/28/07 *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/genplus_dc_01_bin.zip GPDC v01] *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/Genesis_Plus_01_bO.sbi SBIv3.0] | release date=07/26/06| author=[[BlackAura]]| original=[http://cgfm2.emuviews.com/ GenesisPlus] by<br/>Charles MacDonald| systems=Sega Genesis| best=Yes.| isactive=Yes. }} Genesis Plus/DC is a port of Charles MacDonald's Sega Genesis/MegaDrive emulator, Genesis Plus, to the Dreamcast. It is currently the best available Sega Genesis emulator for the Dreamcast platform.It runs full speed on most games without frameskip with sound disabled. ==Features== * Full speed with full sound (no skipping!) * SRAM Saving to VMU * Great compatibility * 2 player support * 6 button pad support * Region settings (JP/US/EU) * .GEN, .BIN, .SMD, and .ZIP support * 2 CPU cores, FAME and C68K * Hardware and software rendering * Fixed graphic bugs from PVR3 version * Mono/Stereo settings (via Dreamcast BIOS) * Nice and easy to use GUI * GPDC is [[GPL|free software]] ===Missing Features=== * 4 player support * Frameskip options for the software renderer * Enhanced sound options ==History== GPDC started as a port of Genesis Plus by Charles Mac Donald. It's been in development since 2003 and a lot of progress has been made since then: BlackAura rewrote the video renderer for the Dreamcast's PowerVR2. Stef D of [http://gens.consolemul.com/ wGens] fame joined the project in 2004 to contribute fast and accurate CPU emulators: C68K & CZ80. Now with Fox68K's new SH4 Z80 emulator FAZE, and FAME, a 68K emulator written in Dreamcast's SH4 assembly language, and BlackAura working on sound emulation, the project has reached its final stage. An official release is expected for the end of this year. ===GPWT=== Until then there's the preview version of GenesisPlusDC Warmtoe & BlackAura released in 07/2006. It is called "GPWT" because it's been the first version to introduce a new GUI written by Warmtoe. ==Controls== ===Button Layout=== *Mega Drive A-Button: (X) *Mega Drive B-Button: (A) *Mega Drive C-Button: (B) *Mega Drive X-Button: (L) *Mega Drive Y-Button: (Y) *Mega Drive Z-Button: (R) *Mega Drive Start-Button: (Start) To exit a running game press (L) + (R) + (Start). ===In the Menu=== (Start) loads a game. Pressing + holding (Up)/(Down) scrolls through your game list. You can skip pages with (Left)/(Right) on the d-pad. To disable/enable 6 button support, press (X). To change the region settings, press (L). ===CPU Settings=== Some details about the different settings: Pressing (B) at the menu changes the CPU emulator. You can select either '''FAME''' - [http://www.m68k.com/fame/ Fox68k]'s great SH4 M68K emulator for fastest emulation, or '''C68K''' - [http://gens.consolemul.com/ Stef D]'s fast and accurate M68K emulator for better compatibility. ===Video Settings=== Press (A) to toggle the graphics renderer. You can select either '''HW''' - Hardware renderer written by BlackAura, using the Dreamcast's PowerVR II DC, very fast but inaccurate in a few games, or '''SW''' - Standard software renderer of GenesisPlusDC by Charles MacDonald, 100% accurate but much slower. ===Recommend Settings=== Recommend settings would be 'Render: HW' with 'CPU: FAME' - if this doesn't work for your game, try 'Render: HW' with 'CPU: C68K' (which is the default setting). ==ROMS.TXT== ===Method 1: Manual creation=== Make sure to rename the actual '.gen', '.bin', or '.zip' roms to not have spaces. ''Examples that'll work:'' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''Comix_Zone_(U)_[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone(U)[!].bin'''' <br /> Rename ''''Comix Zone (U) [!].bin'''' to ''''ComixZone.bin'''' '''''The rest is straight from the readme:''''' In GPWT there is no directory browsing - just that fixed list of names for that fixed list of games. You put your (zipped) ROMS in the directory: \gpwt\data\ROMS It also expects to find a file: \gpwt\data\ROMS.txt In ROMS.TXT you can put the names of your games in there plus the name you'd like to see displayed on screen: SHINOBI.ZIP The Revenge of Shinobi 'SHINOBI.ZIP' (or 'shinobi.zip') would be your actual ROM, 'The Revenge of Shinobi' will be displayed on screen. Each file + name goes into a seperate line in ROMS.TXT. ===Method 2: Provlist by burnerO=== First download this: *Tool Set - [http://www.dcevolution.net/dsdevelopment/large/CE/gpwt-tools.zip Zipfile] Included are Provlist & Renamer which both are needed. 1. Copy your ROMs (*.zip) in /gpwt/data/ROMS/ and run Provlst.exe 2. Open ROMS.LST in Wordpad and replace ".SMC:" with ".ZIP " (space). 3. Save as 'ROMS.TXT' in /gpwt/data/ 4. Right-click on your /gpwt/data/ROMS/ folder and start Renamer 5. Click on 'Edit' -> 'Multi-Change' and replace "%a.SMC" with "%a.ZIP" 6. Click on 'A->B' to apply the changes and then close Renamer ===Method 3: Romlister by Smurph=== Download this application first: *Romlister - [http://www.dcemulation.org/1-newsdump/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Zipfile] 1. Zip all your roms. Keep them in a separate folder apart from the Plainfiles, or SBI, directories. 2. Start the rom lister. 3. Select the ''''data'''' subfolder from the the extracted Plainfiles, or SBI, packages. 4. Select your folder containing your zipped roms, and click on the 'Process' button. ==How To Burn== A little tutorial: ===Using Selfboot Inducer=== *1. At first you need to download [http://sbibuilder.dc-france.com/download/?idsys=2&idcat=15&idfile=115 Selfboot Inducer v4] and install it into C:/SBInducr/. *2. Then download a SBI for one of the GenesisPlusDC versions [http://www.dchelp.net/sbi HERE]. *3. Put this file into your C:/SBInducr/SBI/ folder. *4. Start C:/SBInducr/SBInducer.exe and check the SBI file showing up on the right window. Then select either "Single Menu" or "SBI2Boot" and click on 'Extract SBI'. *5. Browse to the C:/SBInducr/Inducer/gpwt/tools/ directory to find some tools. *6. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *7. Click on the 'CDRecord' button to burn the CD directly, or on the 'DiscJuggler' button to create a '.cdi' image. ===Using BootDreams=== *1. Download Bootdreams from http://dchelp.dcemulation.org, and install it. *2. Extract the plainfiles to their own folder. *3. Using one of the 3 methods listed above, copy your roms to the ROMS folder, and create a ROMS.TXT. *4. Start Bootdreams. *5. Select the folder containing the plainfiles ''''''1st_read.bin''''''. *6. Choose your image type: '''''CDI''''', '''''NRG''''', or '''''MDF/MDS'''''. *7. Click on the process button. *8. Burn the image with your application of choice. To burn straight off Bootdreams, without creating an image, select the "CdRecord" option. To use the Bootdream's image burner select the "ImgRecord" option. ==Downloads== *[https://files.dcemulation.org/software/dreamcast/emulators/genesisplusdc/gpwtlr_v12_by_smurph.zip Smurph's GPWT RomLister v1.2] * Selfboot Inducer Versions: ''(To put both on one disc)'' **[http://dchelp.net/cgi-bin/sbi/browse/browse.cgi?browse&Emus Browse DCHelp's SBI File Repository] The files are called 'GenesisPlusDC-gpwt-260706-BlackAura.sbi', and 'GenesisPlusDC-gpwt-280107-Quzar.sbi'. ==Compatibility== Lists can be found here ''(W.I.P.)'': *[[GenesisPlusDC_BlackAura_list|GenesisPlusDC (BlackAura)]] http://dcemulation.org/1-newsdump/emulators/genesis/genesisplusdc/genplus_dc_01_src.tar.bz2 {{DCWiki:BrokenInternalLinks}} 40a5111e22281350875d7daf7873a0f415892cf8 IntelliMESS 0 793 2908 2648 2023-03-04T06:34:22Z Unknown user 0 wikitext text/x-wiki {{Infobox_Emulator_Information| name=IntelliMESS| image=No Screenshot available| homepage=Unknown| version=V2| downloads=Local links: *[https://files.dcemulation.org/software/dreamcast/emulators/intellimess/intvdc2.zip Plain Files] *[https://files.dcemulation.org/software/dreamcast/emulators/intellimess/InTVDC2_CG.sbi SBIv3.0] | release date=Unknown| last update=Unknown| author=Ian Micheal| original=ice88's M.E.S.S.| systems=Intellivision| best=Unknown| isactive=Unknown }} Developer: Ian Micheal Updated: 2003 An Intellivision emulator based on ice88's M.E.S.S. port. It doesn't have full controller support but does run some games that don't require 16 buttons to play. [https://files.dcemulation.org/software/dreamcast/emulators/intellimess/intv.txt Intellivision M.E.S.S. Final Readme] [[Category:Emulator]] 94113c7caab0082a9222c4e2f4e359a125fbb841 VMU peripheral 0 726 2909 1874 2023-03-11T02:47:49Z Unknown user 0 /* Screen */ wikitext text/x-wiki The VMU peripheral on the [[Maple_bus|Maple Bus]] contains 3 functions: screen, storage, and timer. '''NOTE:''' Some information here is misleading and/or incomplete == Storage == The "block read" and "block write" commands (0x0B and 0x0C) with storage function code are used to read and write blocks of memory in the storage peripheral. Normally, there are 256 blocks of memory that make up the entire storage space, and normally each block consists of 512 bytes. That makes a total of 128 KB of memory. These values are configurable according to the Maple Bus spec, but anything other than these values are not practically usable by most games due to memory access APIs.<ref>''[https://www.dreamcast-talk.com/forum/viewtopic.php?f=5&t=15562&p=171565] TapamN | 400 block VMU on emulator''</ref> === Function Definition === The function definition may be found in the peripheral's [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|device info packet]]. It is necessary to read this word to know how to access blocks of memory on the storage. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | bit 7: removable (1: true)<br>bit 6: CRC (1: needed)<br>bits 0-5: unused (0) || bits 4-7: number of write accesses per block<br>bits 0-3: number of read accesses per block || number of bytes per block<br>(x + 1)*32 bytes || number of partitions (x + 1) |} === Get Media Info === Execute a [[Maple_bus#Commands|get memory information]] command to get information about the size and locations of some information within the media. On successful execution, a [[Maple_bus#Commands|data transfer]] packet with the following payload will be returned. {| class="wikitable" |- ! Word 0 !! Word 1 !! Word 2 !! Word 3 !! Word 4 !! Word 5 !! Word 6 |- | [[Maple_bus#Function_Codes|Function code]] <br> 0x00000002 || 2 most sig bytes: total size <br> 2 least sig bytes: the partition number of this media || 2 most sig bytes: block number of system area <br> 2 least sig bytes: block number of start of FAT area || 2 most sig bytes: number of FAT blocks <br> 2 least sig bytes: block number of file information || 2 most sig bytes: number of file info blocks <br> 2 least sig bytes: icon number || 2 most sig bytes: block number of save area <br> 2 least sig bytes: number of blocks in save area || execution file info |} === Block Read === Execute a sequence of [[Maple_bus#Commands|block reads]] to read data from storage. The number of sequences is dependent on the number of read accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|data transfer]] packet will be returned. === Block Write === Execute a sequence of [[Maple_bus#Commands|block writes]] to write data to storage. The number of sequences is dependent on the number of write accesses per block defined in the function definition above. On successful execution, a [[Maple_bus#Commands|acknowledge]] packet will be returned. After the final write sequence, execute a [[Maple_bus#Commands|get last error]] command with an incremented phase value to commit the block from RAM to storage. * A VMU cannot handle successive block write packets faster than about 10 ms per write ** After such error, the storage functionality acts as if it never received this sequence and never returns a response packet - it may be possible to successfully resend this sequence, but writing a "get last error" command would be necessary before starting over at the first sequence ** The Dreamcast does each read/write sequence on the same cadence as controller polling (about every 16 ms) == Screen == The "block write" command (0x0C) with screen function code and 48 data words is used to write monochrome images to the screen. A screen is 48 bits wide and 32 bits tall. For each bit in the 48 data words, a value of 1 means the pixel is on (black) and 0 means the pixel is off (white). Data is written from left to right and top to bottom (when holding the VMU in the upright orientation i.e. controller flipped upside down). The most significant bit of the first word sets the pixel on the top, left of the screen. The two most significant bytes write to the 33rd through 48th bit of the first row. The next two bytes write to the 1st through 16th bits of the second row. This is repeated for the rest of the 48 words like pictured below. [[File:Dreamcast Screen Words.png|Dreamcast Screen Words]] == Timer == The timer function allows the host to activate the buzzer on the VMU and get button conditions. == References == <references /> 3559c93e9b10573afcd688d398166b6817d893fe Optical drive replacements 0 16 2910 1028 2023-03-12T18:54:06Z Unknown user 0 wikitext text/x-wiki An optical drive replacement is a device that replaces the Dreamcast's [[GD-ROM drive]] with an alternative storage method, typically SD cards or USB storage. These devices typically use an FPGA to simulate the GD-ROM drive hardware. Because these are devices that simulate the system's original GD-ROM, the compatibility is virtually perfect with a few exceptions. Similarly, one could attempt the [[IDE hard drive modification]] to accomplish a similar goal, however as this does not simulate the system's hardware, software hacks must be applied by a loader program, resulting in some potential compatibility issues. {| class="wikitable" !colspan="20"|GD-ROM Optical Drive Features Comparison |- |style="background-color:#c0c0c0;" width="300" | Device: |style="background-color:#d0d0d0;" width="400" | [[GDEMU]] |style="background-color:#d0d0d0;" width="400" | [[USB-GDROM]] |style="background-color:#d0d0d0;" width="400" | [[MODE]] |style="background-color:#d0d0d0;" width="400" | [[iceGDROM]] |- |style="background-color:#d0d0d0;" | price and availability || €130 euros, periodic sales done on [https://gdemu.wordpress.com/ creator's website], price includes shipping from Poland<br>$40-$80 USD unofficial China-based clones widely available worldwide || $180 USD to purchase as a Paypal gift<br>$220 USD to purchase with Paypal protection<br>additional $15 USD for shipping from Russia to worldwide<br>sales through [http://3do-mnemo.com/USB-GDROM_Controller.htm creator's website] || €182, sales through [https://shop.terraonion.com/en/home/17-Terraonion_MODE_Dreamcast_Saturn_ODE.html TerraOnion Shop]<br>|| DIY project |- |style="background-color:#d0d0d0;" width="300" | console revisions supported<br>(none support va2 models) || va1 only<br>(works in va0, but incorrect signal voltages may cause damage) || va0 and va1 || va0 and va1 || va1 only |- |style="background-color:#d0d0d0;" | media type || SD cards || USB 2.0 storage<br>compatible with SATA to USB 2.0 bridges || SD, USB 2.0, SATA<br>SATA through built-in USB 2.0 bridge || SD cards |- |style="background-color:#d0d0d0;" | media capacity || officially, up to 32GB<br>large cards like 400GB and 512GB tested and widely used || up to 2TB || limited by storage device size || ??? |- |style="background-color:#d0d0d0;" | menu type || officially, no menu, controlled by hardware<br>GDMenu graphical menu is current de facto default menu || text-based menu || List view and advanced covert art views || no menu, controlled by hardware |- |style="background-color:#d0d0d0;" | media format || FAT32 with images specifically named and in numbered folders<br>community tools such as GDEmu SD card creator exist to assist in creating cards || FAT32, drag and drop || FAT32, exFAT || FAT32, requires conversion to custom image format, files must be specifically numbered |- |style="background-color:#d0d0d0;" | image format || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, ISO for homebrew disc-swapping (e.g. for emulator ROM discs) || TOSEC GDI+BIN, GDI+ISO, CDI || TOSEC GDI+BIN, GDI+ISO, CDI, CCD+IMG+SUB, MDS+MDF, Redump CUE+BIN/ISO |- |style="background-color:#d0d0d0;" | disc swapping || Yes, swap to next disc by pressing physical button<br>Combined with [[DCDigital]] mod, allows swap to next disc in DCDigital menu || Yes, swap to any disc support<br>Pre-pick swap disc before loading game, and swap using lid open button || Yes || Yes, swap to next disc by ejecting and re-inserting SD card |- |style="background-color:#d0d0d0;" | in-game reset || Yes, reboot console to menu with X+Y+B+A+Start || No, only possible with [[DCDigital]] mod || Yes, reboot console to menu with X+Y+B+A+Start || ??? |- |style="background-color:#d0d0d0;" | custom loader/bleemshell support || allows custom coded menus with direct control of console, can control of disc-swapping done through hidden API<br>Community menus exist including GDMenu, bleemshell, OpenMenu, etc. || none || none || none |- |style="background-color:#d0d0d0;" | bleemcast! GT2/TK3/MGS version support |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) |no<br>(support requires either firmware update to enhance CCD image support, or community effort to further crack protection) | ??? |no<br>(support requires either firmware improvement for image support, or community effort to further crack protection) |- |style="background-color:#d0d0d0;" | known bugs || Item duplication bug on Resident Evil Code Veronica (critical bug, fixed on genuine GDEMU but not clone)<br>Freezing during Skies of Arcadia intro video (non-critical, fixed on genuine GDEMU but not clone)<br>D2 disc swapping bug || ??? || ??? || ??? |- |style="background-color:#d0d0d0;" | additional notes || Genuine devices are firmware-updatable, but clone devices are bricked if user attempts a firmware update<br>Clones are one firmware revision out of date (see above bugs) || Previous versions of firmware included a hidden undisclosed self-bricking timebomb unless user periodically updated firmware in order to give creator control over devices, however the latest version firmware is supposedly free of this since the timebomb was publicized || also supports the Sega Saturn console || completely DIY open source project |} 792129ea63c60eb197d0012440577a6747bd6e1c File:AmigaVMU.png 6 1368 2911 2023-03-12T20:42:41Z Unknown user 0 User created page with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=A sample screenshot of the Amiga VMU development kit.}} |date=2023-03-12 |source={{own}} |author=[[User:Elenydd|Elenydd]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 0011f5cc3f562ffd4c3dc840c00dd69b987742a1 VMU development 0 99 2912 2564 2023-03-12T20:45:42Z Unknown user 0 Added information about the amiga vmu dev kit wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual d89a59f7e92df807367c71de9747a1c0d9faf775 2921 2912 2023-03-25T08:39:09Z Unknown user 0 /* Tips and Tricks */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 512346312c1ad0aed0f4c4a4d3e295918d1906b9 2923 2921 2023-03-26T22:31:06Z Unknown user 0 Added section about connecting VMU to PC. wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 2d690b946a570e11b556378eb263bb84097c8f92 File:VMU Connector Pin-Out.jpg 6 1369 2913 2023-03-25T07:53:42Z Unknown user 0 wikitext text/x-wiki Up-close view of the VMU's connector and pins 1e33207020d386fa1b68cb0565948ee3e04940e6 VMU serial communication 0 1370 2914 2023-03-25T07:59:10Z Unknown user 0 Created page with " [[File:VMU Connector Pin-Out.jpg|600x600px|left|VMU Connector Pin-Out]] {| class="wikitable" |- ! Pin !! Function |- | 2 || CLKi |- | 3 || RX |- | 4 || TX |- | ... || ... |-..." wikitext text/x-wiki [[File:VMU Connector Pin-Out.jpg|600x600px|left|VMU Connector Pin-Out]] {| class="wikitable" |- ! Pin !! Function |- | 2 || CLKi |- | 3 || RX |- | 4 || TX |- | ... || ... |- | 10 || TX |- | 11 || RX |- | 13 || CLKo |} ea70d8470b6a7c80c7266402864828c3ebbc9350 2917 2914 2023-03-25T08:28:25Z Unknown user 0 wikitext text/x-wiki The VMU incorporates a 2-channel synchronous serial interface with data word length of 8-bits. When plugged into the controller, this peripheral is responsible for driving the Maple Communication, enabling the VMU to act as a slave device to the Dreamcast. When plugged into each other, these peripherals allow two standalone VMUs to communicate with one-another. The 2 channels of the peripheral are referred to as SIO0 and SIO1 in the Official Documentation. Features: * 2-channel synchronous serial interface * selectible transfer clock * SIO0 hasa transfer clock with switchable polarity * LSB/MSB switchable start sequence * switchable operation modes * overrun detection * transfer bit length control == VMU-to-Dreamcast Communications == Coming Soon... == VMU-to-VMU Communications == [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU Connectivity]] The VMU also supports connecting to other VMU devices. This allows the the user to transfer files within the file manager of the system BIOS and exchange data within certain VMU games such as Chao Adventure. [[File:VMU-to-VMU Serial.png|thumb|VMU-to-VMU Serial Configuration]] [[File:VMU Connector Pin-Out.jpg|600x600px|VMU Connector Pin-Out]] {| class="wikitable" |- ! Pin !! Function !! Name |- | 2 || CLKi || SCK1 |- | 3 || RX || SI1 |- | 4 || TX || SO1 |- | ... || ... || ... |- | 10 || TX || SO0 |- | 11 || RX || SI0 |- | 13 || CLKo || SCK0 |} NOTE: During VMU-to-VMU file transfers, driven by the BIOS, RX is 1 byte delayed "echo" of TX. 1a9ec7bfc3ff9376976024fa3a3875ce2c350303 2918 2917 2023-03-25T08:33:58Z Unknown user 0 wikitext text/x-wiki The VMU incorporates a 2-channel synchronous serial interface with data word length of 8-bits. When plugged into the controller, this peripheral is responsible for driving the [[VMU_peripheral|Maple Communication]], enabling the VMU to act as a slave device to the Dreamcast. When plugged into each other, these peripherals allow two standalone VMUs to communicate with one-another. The 2 channels of the peripheral are referred to as SIO0 and SIO1 in the [[File:VMU.pdf|Official Documentation]]. Features: * 2-channel synchronous serial interface * selectible transfer clock * SIO0 hasa transfer clock with switchable polarity * LSB/MSB switchable start sequence * switchable operation modes * overrun detection * transfer bit length control == VMU-to-Dreamcast Communications == Coming Soon... == VMU-to-VMU Communications == [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU Connectivity]] The VMU also supports connecting to other VMU devices. This allows the the user to transfer files within the file manager of the system BIOS and exchange data within certain VMU games such as Chao Adventure. [[File:VMU-to-VMU Serial.png|thumb|VMU-to-VMU Serial Configuration]] [[File:VMU Connector Pin-Out.jpg|600x600px|VMU Connector Pin-Out]] {| class="wikitable" |- ! Pin !! Function !! Name |- | 2 || CLKi || SCK1 |- | 3 || RX || SI1 |- | 4 || TX || SO1 |- | ... || ... || ... |- | 10 || TX || SO0 |- | 11 || RX || SI0 |- | 13 || CLKo || SCK0 |} NOTE: During VMU-to-VMU file transfers, driven by the BIOS, RX is 1 byte delayed "echo" of TX. ec71b29e0c1ff30f4001f76d1bdeba906e9c7cdd 2919 2918 2023-03-25T08:35:10Z Unknown user 0 wikitext text/x-wiki The VMU incorporates a 2-channel synchronous serial interface with data word length of 8-bits. When plugged into the controller, this peripheral is responsible for driving the [[VMU_peripheral|Maple Communication]], enabling the VMU to act as a slave device to the Dreamcast. When plugged into each other, these peripherals allow two standalone VMUs to communicate with one-another. The 2 channels of the peripheral are referred to as SIO0 and SIO1 in the official documentation: [[File:VMU.pdf|Official Documentation]]. Features: * 2-channel synchronous serial interface * selectible transfer clock * SIO0 hasa transfer clock with switchable polarity * LSB/MSB switchable start sequence * switchable operation modes * overrun detection * transfer bit length control == VMU-to-Dreamcast Communications == Coming Soon... == VMU-to-VMU Communications == [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU Connectivity]] The VMU also supports connecting to other VMU devices. This allows the the user to transfer files within the file manager of the system BIOS and exchange data within certain VMU games such as Chao Adventure. [[File:VMU-to-VMU Serial.png|thumb|VMU-to-VMU Serial Configuration]] [[File:VMU Connector Pin-Out.jpg|600x600px|VMU Connector Pin-Out]] {| class="wikitable" |- ! Pin !! Function !! Name |- | 2 || CLKi || SCK1 |- | 3 || RX || SI1 |- | 4 || TX || SO1 |- | ... || ... || ... |- | 10 || TX || SO0 |- | 11 || RX || SI0 |- | 13 || CLKo || SCK0 |} NOTE: During VMU-to-VMU file transfers, driven by the BIOS, RX is 1 byte delayed "echo" of TX. c3efebe7b9e2a673b9759e81b22003aecb45b5a3 File:VMU-to-VMU Serial.png 6 1371 2915 2023-03-25T08:00:31Z Unknown user 0 wikitext text/x-wiki VMU-to-VMU Serial Communications 5e8a1bdc71ee23c3809e5b2e66304fc4b747a0b4 File:Dreamcast-VMUs-Hooked.jpg 6 1372 2916 2023-03-25T08:02:51Z Unknown user 0 wikitext text/x-wiki VMU-to-VMU Connectivity 0d61aa66aeef7ff8709597dda833e54b7767e0a4 VMU 0 137 2920 1685 2023-03-25T08:36:07Z Unknown user 0 wikitext text/x-wiki * [[VMU_hardware_overview|Hardware Overview]] * [[VMU_games|Games]] * [[VMU_development|Development]] * [[VMU_emulators|Emulators]] * [[VMU_mods|Modifications]] * [[VMU_peripheral|Peripheral]] * [[VMU_serial_communication|Serial Communication]] {{DCWiki:Stub}} 78405f1fd8896354a3da82c7e6d7a0d87c10ed01 File:VMU2PCAlphaRelease.zip 6 1373 2922 2023-03-26T21:36:30Z Unknown user 0 wikitext text/x-wiki Alpha Release of Parallel and Serial VMU communications software by Soeren Gust add8e364dd5969be7eda143a92dd910b046bded5 VMU2PC 0 1374 2924 2023-03-26T23:05:39Z Unknown user 0 Created a simple page on this software wikitext text/x-wiki VMU2PC is a collection of software allowing the transfer of data between the VMU and a PC. The package contains two programs, Serial2VM, written by Soeren Gust, which uses a serial port with a Atmel microcontroller to convert the logic from the 5v of a typical PC to the 3.3v logic of a VMU. Secondly, VMU2PC, written by John Maushammer, which uses the a parallel port and a custom cable to reduce the voltage for the VMU. Gust's software was used as a basis for Maushammer's approach. You can download it here. == Serial2VM == This approach uses an Atmel AT90S8515 to convert the synchronous serial protocol from the VM into the normal asynchronous serial communication. Sadly the firmware required to create such a cable has yet to be found and likely lost to time. == VMU2PC == This approach uses a custom made cable to transfer the data via a parallel port. You can read about how to create the cable [https://web.archive.org/web/20030210032641/http://www.maushammer.com/portprobe.html here.] The program however it relies on processor loops for timing, which might not be very useful on modern hardware. == Further Reading == Maushammer's page on VMU2PC [https://web.archive.org/web/20030207031204/http://www.maushammer.com/vmu.html] Gust's main page on VMU [https://web.archive.org/web/20021207224951/http://soeren.infoserv.de/vm/Index.html] fb98a410565b4ea303adc6a7ca2e140e54c252ad KallistiOS 0 21 2925 1921 2023-04-01T19:20:56Z Unknown user 0 wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Dan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Megan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of libdream, the first free developer library for Dreamcast. libdream was also written by Megan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. [http://sourceforge.net/project/showfiles.php?group_id=23791&package_id=76380&release_id=144971 libdream source] == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] == Documentation == Up-to-date Doxygen-based documentation of KallistiOS is [https://kos-docs.dreamcast.wiki/ available on the wiki]. eb008df1a9dbc65c791fe2451a72a56ce7746e13 2926 2925 2023-04-01T19:21:14Z Unknown user 0 wikitext text/x-wiki * Website : http://cadcdev.sourceforge.net/softprj/kos/ * Author : Megan Potter, Lawrence Sebald, more == Description == ''description taken from wikipedia'' KallistiOS (KOS) is a free, BSD license-based development system for the Sega Dreamcast game console. The project was initiated in 2000 by Megan Potter, then garnering a team of free software developers over the Internet. Kallisti, from the Greek "to the fairest"; Kallisti OS (Operating System); or the abbreviation KOS, which is pronounced like "Chaos". KallistiOS is the successor of libdream, the first free developer library for Dreamcast. libdream was also written by Megan Potter and published in mid-2000. It served as the basis of some hobby projects, but was soon replaced by KallistiOS. [http://sourceforge.net/project/showfiles.php?group_id=23791&package_id=76380&release_id=144971 libdream source] == Foundation == KOS is the foundation of many, many games and app for the Dreamcast. Not only will it provide you with a unix-type filesystem, it will also handle maple I/O, SD card interface, graphics, sounds, etc. KOS is considered to be the fastest way to get into Dreamcast development, but it comes with some drawback. It has a fairly large memory footprint (2-4 MB???) and isn't the fastest in term of graphics processing. Still, no other solution are as user-friendly (arguably, using Simulant could be considered as an alternative, although it is made using KOS) == Building KOS == KOS is itself a library, but it also prepare your computer to compile code for the Dreamcast as a target. In order to use KOS, you'll need to compile it from source. The process is quite straightforward. * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] == Documentation == Up-to-date Doxygen-based documentation of KallistiOS is [https://kos-docs.dreamcast.wiki/ available on the wiki]. 87dfd055a86cbc6d363e6d2b103db06a49e37a62 Ghetto Pong 0 968 2927 2876 2023-04-01T19:21:54Z Unknown user 0 wikitext text/x-wiki Ghetto Pong is a pong clone by Jordan DeLong and [[Megan Potter]]. https://files.dcemulation.org/software/dreamcast/games/ghettopong/ghetto_pong_10final_binary.tar.gz 4e99b0bbd5249ce77fbb345fa231863da1da2aaf DCPaint 0 1075 2928 2287 2023-04-01T19:22:17Z Unknown user 0 wikitext text/x-wiki Dream Paint v0.01 ----------------- Changes (since the first unnumbered release) ------- *Added a simple GUI (borrowed from DCDraw by Tom Waters) *Made a cursor you can actually see. *Added choice of line thickness. *Fixed some bugs. Known bugs ---------- *Quit in the GUI doesn't work right (just press the side mouse button instead) *Drawing with a thick line on right side of screen draws over the GUI Credits ------- *Megan Potter for LibDream - http://dcdev.allusion.net *Tom Waters for DCDraw - http://members.tripod.co.uk/tom_waters/dreamcast *Jules for getting me started - http://newbie.julesdcdev.com *DCEmulation - http://www.dcemulation.org *Andrew Kieschnick - http://dcload.julesdcdev.com/ *Marcus Comstedt - http://mc.pp.se/dc/ All the developers and everyone else helping to keep the "Dream" alive. David Persik dpersik@hotmail.com 4f2dc8fb9f1c6d9a4e3577c2ec5f08b283bbd57e Ken Friece 0 809 2929 2285 2023-04-01T19:23:15Z Unknown user 0 wikitext text/x-wiki Ken Friece was a Dreamcast developer. He started developing [[NesterDC]] together with [[Takayama Fumihiko]]. When version 3.0 of NesterDC was released, Takayama took over the project and Ken retired from the project. ==Links== *[http://nesterdc.emulation64.com Ken's NesterDC-Website] ==Interview with Ken Friece== '''DCEmulation: So, Ken where are you from and how old are you?''' Ken Friece: I am 24 and originally from Columbus, OH. My current job took me to the Washington DC area, where I have been for the past year. '''DCEmulation: How long have you been programming?''' Ken Friece: I started programming around 3 years ago, and have been hooked ever since. :) '''DCEmulation:''' Currently, you have gotten a good grasp of Megan Potter's libdream, but what did you start off programming with (pc and tools) when you first started to seriously program as a hobby?''' Ken Friece: I started programming in C++ using g++ in a unix environment, doing college programming assignments. Most of the programming that I have done has been in unix, linux, or cygwin, using C or C++. '''DCEmulation: What past projects have you done? (hobby projects)''' Ken Friece: Nothing major. I wrote a Yahtzee game in java to learn the language. Other than that, the most challenging thing that I did was code a simple compiler in C for a college project. '''DCEmulation: What are you working on next with NesterDC? Do you have any other projects in the works? :)''' Ken Friece: Sound will be my number one priority in version3. Another possible improvement is a better user interface. I have received many emails from people about how difficult it is to navigate through the game selecton menu with 1000+ games. I really don't understand why people have that many games, considering only a handful of them are GOOD!!! Although I haven't started another project yet, a few other ports have been getting some serious thought lately. '''DCEmulation: When did you come up for the idea for NesterDC?''' Ken Friece: I stumbled upon Megan Potters site and compiled ghetto pong. The idea of programming for a console was awesome. I started to change things around in ghetto pong, and was also looking at the source code to nester. That's when the idea came to me. The Dreamcast already had ngine-snes9x, sintendo, and DreamSNES, so another SNES emu would be pointless. I knew that I could port nester from looking at ghetto pong source, libdream examples, and nester source. I looked at the source code from many emulators, and nester seemed to be one of the most well organized and coded. '''DCEmulation: After your last release, I've been salivating. When might the next release be?''' Ken Friece: If I told you then I would have to kill you :) Just kidding, I don't even know when the next release will be. Giving a date will just disappoint people if I can't make it, and add stress to the project. Remember, NesterDC is a hobby. '''DCEmulation: Ken, when did you get into the DC Emulation scene and what do you think about it?''' Ken Friece: I got into the DC Emulation scene around 7 months ago, and have enjoyed every minute of it. Its great to see a new project pop up, and existing projects improve. 0405947cda22d80bba0335b89eed130e6ee0feb5 Feet of Fury 0 987 2930 2283 2023-04-01T19:23:50Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="2" | {{{name|Feet of Fury}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="2" | {{{image|[[Image:FeetOfFuryPackshot_p.jpg|250px|thumb|Copyright: Cryptic Allusion]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|http://www.cagames.com/}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>Purchase</i>}}} |- stylbackground:#ffffff" |Release Date || {{{release date|06/07/03}}} |- style="background:#ffffff" |Author || {{{author|Cryptic Allusion}}} |- style="background:#ffffff" |Type of game || {{{type|Dance Dance Revolution Clone}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==Independent Review== [[Image:FeetOfFuryScreen02_p.jpg|thumb|left|320px|Copyright: Cryptic Allusion]] Written by MetaFox, October 22, 2005 Source: [http://web.archive.org/web/20060918192734/http://dreamon.cyberdogcastle.com/index.php?n=Main.FeetOfFury DreamOn/CyberDogCastle via Archive.org] In 2003, Cryptic Allusion Games made history by releasing the first commercial independent Dreamcast game written with free development libraries. We did some extensive hands on playing of the game, and sat down with the creators of the game, Megan Potter and Roddy Toomim for a quick Questions + Answers session regarding Cryptic Allusion, Feet of Fury, and their upcoming game, Tryptonite. (The Q+A will be available in the print version of Dream On, available in the fourth quarter of 2005) Feet of Fury is a dancing game that borrows many elements from Konami's Dance Dance Revolution Series of games. You have a set of arrows that you must follow, while keeping your steps to the music. The main difference of Feet of Fury, and the element that sets it apart, is that the game is focused more on strategy and beating your opponent. There are power ups and power downs on the board. Hitting an arrow that contains an icon may cause the speed of the arrows to slow down or speed up, or it might cause the arrows to reverse direction. [[Image:FeetOfFuryScreen01_p.jpg|thumb|right|320px|Copyright: Cryptic Allusion]] Because of this element, the multiplayer mode in Feet of Fury is awesome. Another addition is the health bar. At the end of the round, the person with the most health is the winner. It adds a lot more to this type of game when you have to worry about your opponent hitting you with powerdowns, and throwing your feet around on the dance mat like an idiot, all while trying to keep your health bar full. The single player mode is no slouch either. There are a good number of songs to play and unlock. Each song has a good tempo to it, and fits this type of game really well. There are a number of hidden characters and features to be unlocked, so the game will keep you entertained for hours. When you get sick of all that dancing, you can let your fingers do the dancing with what is in my opinion, the coolest thing to happen to dance games since their invention: The Typing of Fury mode. In this mode, letters fly up on screen instead of arrows, and you use your Dreamcast keyboard to match the letters to the beat while spelling out words. This mode is very challenging, and surprisingly, very fun. When you add multiple keyboards to the action for some multiplayer mayhem, you'll see the pure hilarity that ensues. This is a top notch addition, and is a lot less of a gimmick than you might think. Take your dusty underused keyboards out of the attic, and set them up for some furious typing, you won't regret it. Summary: Good songs, multiplayer battle elements, unlockables, and Typing of Fury make this game a good investment, and an example for future independent developers to follow. '''Overall rating:''' 4 / 5 Purchase it at the [http://www.goatstore.com GOAT Store]. = Interview with Roddy, a.k.a. DJ Geki= This interview with [[DJGeki]] was taken by [[MetaFox]] for the DreamOn magazine #1, which was released at the Midwest Gaming Classic in 2004. '''How did you first become associated with Cryptic Allusion?''' This is a long story, so I'll try to get right to the point: I met Dan at the University of Texas through a mutual friend who wanted to start a game business within the next few years. Even though that company never got started, Dan's "demo group" named Cryptic Allusion was just kind of 'there' and we decided to make something of it after we got started on Feet of Fury. FoF was originally planned to be a free-release game, with just a few of my own songs in it. Nothing fancy...but it blew up into a full-size project after we decided that this might be our shot to "break into" the elusive boys-club that the industry seems to be. We're finally starting to see some of the effects of that now (i.e., EGM taking notice of the DC homebrew community), and I'd like to think that the commercial release of FoF had something to do with the rise in interest. '''What was your position for Feet of Fury?''' I played quite a few roles. I was first and foremost the primary composer of music and sound effects for FoF. I did around 20 tracks and loops specifically for the game. Don't even ask me to count how many sound effects I made. Secondly, I was the business contact and "department head" for all things that involved licensed music. I also gave a lot of feedback to Dan about gameplay, came up with some ideas for items/attacks present in the game, some menu structures, and other design ideas that never quite got to the "complete idea" phase. :) I also ended up vetoing some gameplay along with Dan so that the game would be a more enjoyable experience. That was mostly his idea, though... I think I'm a packrat when it comes to gameplay options. I almost never want to get rid of anything! '''Do you have a preference for the style of music that you make, or do you feel comfortable making music encompassing any genre?''' Woo...there's a toughie. A preference for the style of music I make... I'd like to say I don't have a preference. I enjoy dance music in general, but there are specific genres I don't like, and others that I prefer; however, I feel that if I needed to make something specific, I could do the research and make it happen (yes, even country music...FEH!). As was seen in the bonuses included on the FoF disc, I am capable of composing classical-type music. It may not be John Williams nor Mahler, but I kind of like what comes out of my brain. Now that I've danced around your question, let's see if I can answer it. I really like Breakbeat. I'd love to be able to get into doing some stuff that sounds more like it, but right now whenever I let my mind take over the music-making process, everything becomes jazz-like. Meaning, there's no real hook to most of my songs, as the melodic lines just tend to take themselves in whichever direction they please. '''Is there anything that you wish Feet of Fury could have had if it had a bigger budget and a longer development cycle?''' I think that if we'd had some capital, we might have paid for the first run of discs on our own. It's just technically simpler that way than going through a 3rd party. More specifically, we had planned for animated characters fighting in mid-screen (a la "Puzzle Fighter"), and a "charge up" mode that could have been extra special. It's way too involved to describe here, but it would have taken a longer amount of time to program this mode. It also would have removed FoF many steps away from DDR (no pun intended), not to mention that it was relatively intuitive, and made gameplay much more interesting. This mode could have replaced "Item Battle" as the main mode, but there wasn't enough time or complete ideas to make it happen. It broke quite a few rules from the standard DDR-style play. '''The thing that really makes Feet of Fury stand out from other music games is the typing of fury mode. What are your opinions on this feature?''' My opinion is that Dan is a freaky genius. Not a "Freaking Genius" (although he is that), but "freaky". I think he played "The Typing of the Dead" one too many times :D Excellent, excellent use of the existing engine to make up a totally different game. It's way too hard though :) It was all his idea, in case you couldn't infer that from my statements, but I really do enjoy getting my butt handed to me by the computer. '''What are your thoughts on the commercial future of the Dreamcast in the homebrew realm?''' The commercial future doesn't look amazing _right now_, but it's by no means going to go away or die. I think we're just off to a slow start.You give this scene another two years, and I think we may have an explosion of epic proportions on our hands. I mean, the DC is still new in the way of dead systems. Once our current lot of systems decides to die out, there will be a lull in terms of new games for the new slew of systems. In that time, we won't see anything interesting minus the "graphic demo" release titles that we're bound to see. You know the kind... the ones that "push 3D reality to the next level" and such. I just get this feeling that people are going to turn back to their old systems (like they usually do) and see that they had something great in the Dreamcast. Lots of quality games, the systems are super cheap (when you can find them), and the accessories are pretty much ubiquitous. Ooh...I used "ubiquitous"! (and it made sense!) '''There have been talks lately about making producingDreamcast shareware games as were done quite alot for the PC and Amiga in the early 1990s. What are your thoughts on this?''' I'm all for it! I LOVE shareware. I remember going to high school (way back in 1992-96) always having a store-bought shareware copy of Doom in my backpack. Any chance I got, I'd install that sucker on an 486 and impress the hell out of whoever was around. I used to go to the WaldenSoftware store in our local mall just so I could watch the bad-assness of the demos on the Amiga 500 they had on display. That was also the first time I'd ever seen "Shadow of the Beast". God bless thee, Psygnosis. Too bad Sony bought them out. In any case, I never had an Amiga until around 2 years ago, so I didn't really get into the demo scene back then. It looks like it was a good time for all from what I've seen recently of that era. Dan is the big proponent of DC shareware, and at first I was opposed to it. What section of the mass-market wants to download something for a console system? But the more I think about it, the more I like it: Johnny downloads the shareware, burns it to a disc and goes off to show his friends. They like it, so he gives them a copy legally. Legally? Wait a second...that shouldn't be! Ah, but it is my good consumer. Eat it up! Shareware games don't happen as much as they should these days. Let's hope this idea takes off. '''Any insight towards what Cryptic Allusion has planned for the future?''' Heh heh...i do i do. We hinted a bit at the RPG we had been working on (on the FoF disc) until we started in on Feet of Fury. I'd love to get a team to finish that. There is so much groundwork laid down, and yet so much left to do. It's just a project I'd love to take up again. Other than that, I came up with an idea for an online game that is quite unlike any games we've really seen here. It would require a relatively large budget (well, relatively large compared to $0.00), though, so don't look forward to that anytime soon. In any case, we do have lots of stuff planned, just nothing has been made solid yet as far as what our next project will be. I'd be expecting an announcement from us semi-soon, though. Maybe not something ground breaking, but definitely something worth looking forward to. Especially if you like old-school games. :D '''Thanks for taking the time to answer these questions, and sorry for procrastinating so much to get them to you.''' No prob. Hope you get these off in time to get them into the mag :) Good luck with it, and let us know when it's finished so I can buy a copy or twelve! BTW, it seems that Dan never received any questions, are you going to interview him as well? 6881ceeb221929d5e52e007403c1e237be6baacd 2936 2930 2023-04-01T19:28:14Z Unknown user 0 wikitext text/x-wiki {| border="0" cellpadding="2" cellspacing="1" align="right" style="margin-left:1em; background:#CADCFB;" !colspan="2" | {{{name|Feet of Fury}}} |- border="0" cellpadding="2" cellspacing="1" align="center" style="margin-left:1em; background:#ffffff;" !colspan="2" | {{{image|[[Image:FeetOfFuryPackshot_p.jpg|250px|thumb|Copyright: Cryptic Allusion]]}}} |- style="background:#ffffff" |Homepage || {{{homepage|http://www.cagames.com/}}} |- style="background:#ffffff" |Downloads || {{{downloads|<i>Purchase</i>}}} |- stylbackground:#ffffff" |Release Date || {{{release date|06/07/03}}} |- style="background:#ffffff" |Author || {{{author|Cryptic Allusion}}} |- style="background:#ffffff" |Type of game || {{{type|Dance Dance Revolution Clone}}} |- style="background:#ffffff" |[[Refresh Rate]] || {{{refreshrate|<i>Unknown</i>}}} |} ==Independent Review== [[Image:FeetOfFuryScreen02_p.jpg|thumb|left|320px|Copyright: Cryptic Allusion]] Written by MetaFox, October 22, 2005 Source: [http://web.archive.org/web/20060918192734/http://dreamon.cyberdogcastle.com/index.php?n=Main.FeetOfFury DreamOn/CyberDogCastle via Archive.org] In 2003, Cryptic Allusion Games made history by releasing the first commercial independent Dreamcast game written with free development libraries. We did some extensive hands on playing of the game, and sat down with the creators of the game, Megan Potter and Roddy Toomim for a quick Questions + Answers session regarding Cryptic Allusion, Feet of Fury, and their upcoming game, Tryptonite. (The Q+A will be available in the print version of Dream On, available in the fourth quarter of 2005) Feet of Fury is a dancing game that borrows many elements from Konami's Dance Dance Revolution Series of games. You have a set of arrows that you must follow, while keeping your steps to the music. The main difference of Feet of Fury, and the element that sets it apart, is that the game is focused more on strategy and beating your opponent. There are power ups and power downs on the board. Hitting an arrow that contains an icon may cause the speed of the arrows to slow down or speed up, or it might cause the arrows to reverse direction. [[Image:FeetOfFuryScreen01_p.jpg|thumb|right|320px|Copyright: Cryptic Allusion]] Because of this element, the multiplayer mode in Feet of Fury is awesome. Another addition is the health bar. At the end of the round, the person with the most health is the winner. It adds a lot more to this type of game when you have to worry about your opponent hitting you with powerdowns, and throwing your feet around on the dance mat like an idiot, all while trying to keep your health bar full. The single player mode is no slouch either. There are a good number of songs to play and unlock. Each song has a good tempo to it, and fits this type of game really well. There are a number of hidden characters and features to be unlocked, so the game will keep you entertained for hours. When you get sick of all that dancing, you can let your fingers do the dancing with what is in my opinion, the coolest thing to happen to dance games since their invention: The Typing of Fury mode. In this mode, letters fly up on screen instead of arrows, and you use your Dreamcast keyboard to match the letters to the beat while spelling out words. This mode is very challenging, and surprisingly, very fun. When you add multiple keyboards to the action for some multiplayer mayhem, you'll see the pure hilarity that ensues. This is a top notch addition, and is a lot less of a gimmick than you might think. Take your dusty underused keyboards out of the attic, and set them up for some furious typing, you won't regret it. Summary: Good songs, multiplayer battle elements, unlockables, and Typing of Fury make this game a good investment, and an example for future independent developers to follow. '''Overall rating:''' 4 / 5 Purchase it at the [http://www.goatstore.com GOAT Store]. = Interview with Roddy, a.k.a. DJ Geki= This interview with [[DJGeki]] was taken by [[MetaFox]] for the DreamOn magazine #1, which was released at the Midwest Gaming Classic in 2004. '''How did you first become associated with Cryptic Allusion?''' This is a long story, so I'll try to get right to the point: I met Megan at the University of Texas through a mutual friend who wanted to start a game business within the next few years. Even though that company never got started, Megan's "demo group" named Cryptic Allusion was just kind of 'there' and we decided to make something of it after we got started on Feet of Fury. FoF was originally planned to be a free-release game, with just a few of my own songs in it. Nothing fancy...but it blew up into a full-size project after we decided that this might be our shot to "break into" the elusive boys-club that the industry seems to be. We're finally starting to see some of the effects of that now (i.e., EGM taking notice of the DC homebrew community), and I'd like to think that the commercial release of FoF had something to do with the rise in interest. '''What was your position for Feet of Fury?''' I played quite a few roles. I was first and foremost the primary composer of music and sound effects for FoF. I did around 20 tracks and loops specifically for the game. Don't even ask me to count how many sound effects I made. Secondly, I was the business contact and "department head" for all things that involved licensed music. I also gave a lot of feedback to Megan about gameplay, came up with some ideas for items/attacks present in the game, some menu structures, and other design ideas that never quite got to the "complete idea" phase. :) I also ended up vetoing some gameplay along with Megan so that the game would be a more enjoyable experience. That was mostly his idea, though... I think I'm a packrat when it comes to gameplay options. I almost never want to get rid of anything! '''Do you have a preference for the style of music that you make, or do you feel comfortable making music encompassing any genre?''' Woo...there's a toughie. A preference for the style of music I make... I'd like to say I don't have a preference. I enjoy dance music in general, but there are specific genres I don't like, and others that I prefer; however, I feel that if I needed to make something specific, I could do the research and make it happen (yes, even country music...FEH!). As was seen in the bonuses included on the FoF disc, I am capable of composing classical-type music. It may not be John Williams nor Mahler, but I kind of like what comes out of my brain. Now that I've danced around your question, let's see if I can answer it. I really like Breakbeat. I'd love to be able to get into doing some stuff that sounds more like it, but right now whenever I let my mind take over the music-making process, everything becomes jazz-like. Meaning, there's no real hook to most of my songs, as the melodic lines just tend to take themselves in whichever direction they please. '''Is there anything that you wish Feet of Fury could have had if it had a bigger budget and a longer development cycle?''' I think that if we'd had some capital, we might have paid for the first run of discs on our own. It's just technically simpler that way than going through a 3rd party. More specifically, we had planned for animated characters fighting in mid-screen (a la "Puzzle Fighter"), and a "charge up" mode that could have been extra special. It's way too involved to describe here, but it would have taken a longer amount of time to program this mode. It also would have removed FoF many steps away from DDR (no pun intended), not to mention that it was relatively intuitive, and made gameplay much more interesting. This mode could have replaced "Item Battle" as the main mode, but there wasn't enough time or complete ideas to make it happen. It broke quite a few rules from the standard DDR-style play. '''The thing that really makes Feet of Fury stand out from other music games is the typing of fury mode. What are your opinions on this feature?''' My opinion is that Megan is a freaky genius. Not a "Freaking Genius" (although she is that), but "freaky". I think he played "The Typing of the Dead" one too many times :D Excellent, excellent use of the existing engine to make up a totally different game. It's way too hard though :) It was all his idea, in case you couldn't infer that from my statements, but I really do enjoy getting my butt handed to me by the computer. '''What are your thoughts on the commercial future of the Dreamcast in the homebrew realm?''' The commercial future doesn't look amazing _right now_, but it's by no means going to go away or die. I think we're just off to a slow start.You give this scene another two years, and I think we may have an explosion of epic proportions on our hands. I mean, the DC is still new in the way of dead systems. Once our current lot of systems decides to die out, there will be a lull in terms of new games for the new slew of systems. In that time, we won't see anything interesting minus the "graphic demo" release titles that we're bound to see. You know the kind... the ones that "push 3D reality to the next level" and such. I just get this feeling that people are going to turn back to their old systems (like they usually do) and see that they had something great in the Dreamcast. Lots of quality games, the systems are super cheap (when you can find them), and the accessories are pretty much ubiquitous. Ooh...I used "ubiquitous"! (and it made sense!) '''There have been talks lately about making producingDreamcast shareware games as were done quite alot for the PC and Amiga in the early 1990s. What are your thoughts on this?''' I'm all for it! I LOVE shareware. I remember going to high school (way back in 1992-96) always having a store-bought shareware copy of Doom in my backpack. Any chance I got, I'd install that sucker on an 486 and impress the hell out of whoever was around. I used to go to the WaldenSoftware store in our local mall just so I could watch the bad-assness of the demos on the Amiga 500 they had on display. That was also the first time I'd ever seen "Shadow of the Beast". God bless thee, Psygnosis. Too bad Sony bought them out. In any case, I never had an Amiga until around 2 years ago, so I didn't really get into the demo scene back then. It looks like it was a good time for all from what I've seen recently of that era. Megan is the big proponent of DC shareware, and at first I was opposed to it. What section of the mass-market wants to download something for a console system? But the more I think about it, the more I like it: Johnny downloads the shareware, burns it to a disc and goes off to show his friends. They like it, so he gives them a copy legally. Legally? Wait a second...that shouldn't be! Ah, but it is my good consumer. Eat it up! Shareware games don't happen as much as they should these days. Let's hope this idea takes off. '''Any insight towards what Cryptic Allusion has planned for the future?''' Heh heh...i do i do. We hinted a bit at the RPG we had been working on (on the FoF disc) until we started in on Feet of Fury. I'd love to get a team to finish that. There is so much groundwork laid down, and yet so much left to do. It's just a project I'd love to take up again. Other than that, I came up with an idea for an online game that is quite unlike any games we've really seen here. It would require a relatively large budget (well, relatively large compared to $0.00), though, so don't look forward to that anytime soon. In any case, we do have lots of stuff planned, just nothing has been made solid yet as far as what our next project will be. I'd be expecting an announcement from us semi-soon, though. Maybe not something ground breaking, but definitely something worth looking forward to. Especially if you like old-school games. :D '''Thanks for taking the time to answer these questions, and sorry for procrastinating so much to get them to you.''' No prob. Hope you get these off in time to get them into the mag :) Good luck with it, and let us know when it's finished so I can buy a copy or twelve! BTW, it seems that Megan never received any questions, are you going to interview her as well? 60b9a3848cc1b87464fb0c0deb6725311ec53bd7 SvOlli 0 996 2931 2183 2023-04-01T19:24:20Z Unknown user 0 wikitext text/x-wiki SvOlli was a German Dreamcast developer and he released [[Stella DC|DCStella]]. We have an [[Interviews:SvOlli|interview]] with him on our site. *[http://www.svolli.org/software/dcstella/ SvOlli's DCStella website] This interview was by DarthEmuFan on 3rd March 2002 for ConsoleVision.com. '''Consolevision: Where were you born, raised, personal details, etc?''' SvOlli: Born and raised in a small town called Lehrte near Hannover, Germany (the town of the Expo 2000 and the world's biggest computer fair, the CeBit). Moved to Hannover in May 2000. Only child, born '72, zodiac sign pisces, not married. '''Consolevision: What qualifications do you have? College degree's?''' SvOlli: Right now I'm writing my diploma thesis, but I already have several years of professional experience from jobbing which kept me off my diploma. Jobs includes ones from administration stuff to coding at Germany leg of the OS manufacturer QNX. '''Consolevision: What got you interested in computers?''' SvOlli: Hard to say. I've been hooked on tin-soldering by watching my dad. But I'm not nearly as good as him, though. After getting an Atari 2600 VCS, I was fascinated by the idea of the "virtual worlds" though they weren't called like that back then, in the C64 I saw the perfect combination of playing games and toying with technique behind it. That facination for the technique faded a bit away when the C64 went way out of state of the art. The last time I really used mine was 1992. From there I went to AMIGA, but couldn't really make good friends like I did with the C64, so my interest faded away another bit. It came back, when I got first contact with Unix (SunOS 4.1, to be more precise) on my studies at the univerity. Mostly the whole networking / remote stuff I got hooked on. I learned that there is a widely source code compatible free Unix for installation on PCs, called Linux (1.0.9 was my first self-compiled kernel). That got me into buying a PC, which I hated back then for MS-DOS and Windows 3.1. '''Consolevision: What project(s) have you done in the past?''' SvOlli: I'm still listed as a developer of sorcerer, a Linux distribution that's based on compiling source code when installing a package instead of using precompiled binaries. I put my work there on hold 'till my diploma's finished. In general you could say that I'd rather like contributing to other peoples projects, than beginning (and finishing) my own. If I think the software I use is lacking a feature, I'll take a look if I can hack it in there myself instead of asking the author to do so. The times I succeeded I sent the patches of my work to the original authors. Isn't that just a wonderful thing about open source software? I did that on several Unix utilities, including wmx, an X11 window manager. '''Consolevision: What made you get into the Dreamcast Homebrew scene?''' SvOlli: For gaming I got myself a PSX when the prices got reasonable. That one I built in an arcade cabinet once, running Namco and other museums. But then came the time I noticed that the PSX is too limited for a good allround emulator. My attempts on putting a PC in there resulted in two wrecked keyboards, so I looked for an alternative. I was playing Soul Calibur and other DC titles with a friend of mine, and he told me Mame is also available for DC. Since DCs are on the runout, they are cheap, so I bought one with Soul Calibur. Looking for Mamed I stumbled over the terms "coders cable" and other stuff concerning homebrewing software. DCStella was the very first thing I did on homebrewing after toying a bit around with KOS and dc-load and stuff. Seeing [d]cs2600 I was disappointed. I knew Stella for Linux and I liked that one much better, so I assumed that someone must have already ported it. Much to my surprise, my search was fruitless. And like every qualified villian states in the movies: "If you want get something done, you got to do it yourself." So I started to analyse the source on how to replace the screen output by the one on the DC. By just using the frame buffer it was not a very hard thing to do. The prove of concept was made. There was the birthday of the guy who got me into the DC in the first place was about 3 weeks after of my first sight of a running emulation. So I hacked the v0.1 (called alpha1) back then together quickly, and on his birthday I presented him a rather unimpressive 3"-CDR with the Atari Logo as the title saying: "This is the Stella Emulator for Dreamcast. I just ported it. This one here in my hand is the very first copy of it. Happy Birthday." - "Just a moment. Does this mean I can finally play the old Atari games in rgb quality like I always wanted?" - "Yep." - (then there was a twinkle in his eyes) "Cool." '''Consolevision: What made you choose to do an emulator for the Atari 2600 and how complex is it a machine to emulate?''' SvOlli: It was always the wish to have a DC version of Stella. I wanted to play some games of my childhood again, and I knew Stella for several years, I already poked around in the source once in a while when I got the time and was curious about some details of one or another 2600 game. So I knew the source was well organized and highly portable. And that's the point: I just did a port not a complete emulator. So I don't know a lot about emulation, the whole emulation just looks like a precompiled library to me that's called once for initialization and again once for every frame to process. '''Consolevision: Would you say that it is an easier to port emus over from linux rather than rewrite them specifically for the dreamcast?''' SvOlli: Definitively, yes. Graphics, sound and input need to be rewritten, but the core is still the same. This also can turn to a downside: I'm using some rather generic and not DC optimized source, so it'll be slower than a tweaked one. Have a look at the [[DreamSNES]] emulator: the machine they emulate is much more complex and it runs at roughly the same speed as [[DCStella]]. Awesome job done there. '''Consolevision: What programs have helped you bring Stella to the Dreamcast?''' SvOlli: About the same all others help to bring their software to Dreamcast: the gcc-toolchain done by [[M.R.Brown]], [[AndrewK]]'s [[dc-load]], [[Megan Potter]]'s [[KallistiOS|KOS]] and [[libdream]]. A texteditor for writing / modifying the source, nothing far apart from the tools I use for writing Unix sources. '''Consolevision: Do you have plans for updating [[DCStella]] or are you happy with what is an exceedingly good emulator already?''' SvOlli: Though I'm quite pleased with it like it is now, I still have some plans, but most of them I hold of until I finished my diploma thesis, since they could prove to be rather time consuming. First of all I want the VMU image to be also themeable, probably even themeable for each ROM loaded. Second would be a monitor to go searching for cheats, because I want to play Solaris to the end someday. There are also open issues to be solved, like the paddles and the sound that's just not like the original Stella. I'm still curious of the feature requests that will come in the future, like the one ROM autostart feature would never have gone in, if nobody asked. But there are already some requests that I had to turn down, like support for 7800 games, since I only do (and only want to do) the port of Stella, there's no real ambition to supercede the emulation capabilities of the original Stella. Well, I've implemented an illegal opcode in the original Stella sources though, but that's an exception to the rule and was also rather easy to do. But these changes have already been submitted for inclusion on the original Stella. '''Consolevision: The themeable VMU images, surely that is a massive undertaking, would you seek help from the dreamcast scene to make them?''' SvOlli: Not really. That's something I'd like to hack in there myself. On the other hand if someone reads this, likes the idea and sends me a patch, it will go in there and save me work. But that's not help I seek out for. Where I really could use help is the darned paddles routine. It refuses to work and after several days of bug-hunting I still have no idea what's broken. Maybe I'm blind for the obvious, maybe it's some typecasting or endian problem, I just don't know. Finally one could say that porting Stella has is small enough for a project where someone could do all by himself, but it's still big enough for others to offer their ideas. That's one of the ideas in releasing the source: if someone has a cool idea and some skills, he can download the source, see if his idea you work, without the need to ask me for anything. That's something that bugs me about most of the DC homebrew releases: I have an idea for a feature but fail to see if it's really doable, since I can't take a look at the sources. If it wouldn't be for Megan Potter, each homebrewer would be forced to reinventing the wheel. '''Consolevision: Whats your favourite Atari 2600 game and why? :)''' SvOlli: I don't have that one game, since my taste changes quite often in details, but it's always something that's unique to Atari 2600 in idea and gameplay like Adventure or Haunted House. Or maybe some of these cool party two player games like Combat, Outlaws or Pele Soccer. The game I will be spending on most time in 2002 is going to be Solaris, since I want to beat that one with all it includes: drawing maps and stuff :) '''Consolevision: Would you consider doing any other projects for the dreamcast or for that matter the Game Boy Advance for that matter?''' SvOlli: Yes, absolutly. I want to do my own mp3 player using KOS and the mp3/oggvorbis libraries, since I want one that's also usable without the need for a monitor, so all output will be displayed on the VMU. Linux on DC is also something very tempting for doing a quick hack like porting FreeCiv, for example. But setting up a cross compiling suite for Linux is a bit more difficult than for a bare cross compilation kit, like it's needed for KOS and libdream. And Linux would be also a quite nice platform to see if porting of software would make sence. I'm thinking about VICE for example. If that Commodore emulator runs painfully slow on the DC one can skip the try in porting it to KOS. The other ideas I have are rather the result of sheer need, like I need some software for backing up the VMU, so if no one does it until summer I'll hack a tool together that allows you to save and load your vmu over dc-load. About the GBA I'm not so sure, I guess if I want something portable to toy around with, I'd rather go for a Linux-PDA. '''Consolevision: Wow, you have some great projects and we wish you luck :) What's your opinion of the Dreamcast scene and the fact that through people such as your self we the fans can play great vintage games on a state of the art console?''' SvOlli: Thanks. When Sega chose the name Dreamcast I'm they didn't think of it as the "Dream" of the homebrew scene. But imho it is, it's the platform with the best access for homebrewers and people using their work: no modifications needed for booting homebrew CDs, developer's cable for $25 and enough infos on the web to get started without bothering anybody. That's what I did, that makes it a dream. About the fans enjoying my work I'd like to say that you're the one pushing the project forward. Over 1300 diffrent machines (ips) from the internet downloaded DCStella V0.2, V0.2a and V0.2b from my site in February. That's encouraging. Overall it's a nice community to participate in, though some more homebrewers wouldn't hurt. The only sad thing is that at the end of 2002 it will be dead on the commercial scene like any other discontinued system. History repeating itself there: bad concepts seem to sell better, just take a look at VHS, Microsoft and even Sony's going to get in line with them. Someone once said that the Dreamcast is like the Amiga of the console world. There's no comparison on the Dreamcast that could be more true and that gives me hope, since no one dies harder than an Amiga die hard, or a DC die hard for that matter :-). '''Consolevision: For the last question: What would be the emulator/homebrew software etc you would most like to see appear on the Dreamcast?''' SvOlli: VICE! What's lacking now is a good C64 emulator, and VICE is the best portable of them all, just one single assembler line (and that one's in the DOS port), and already ported to six platforms, have a look at http://viceteam.bei.t-online.de/ There's also some other stuff that I would like to see more evolving, like ScummVM for example. If I take a look at the site promoting open source projects like freshmeat.net or sourceforge.net, I feel like a child in the candystore not knowing what to pick first. And there's also one thing I'd like to see more happening on the DC homebrew scene and that's more sharing of the source. d089267b11b621483fc5f50fe3fbfd789276a225 Cryptic Allusion 0 1055 2932 2261 2023-04-01T19:25:19Z Unknown user 0 wikitext text/x-wiki Cryptic Allusion is a software development group led by Megan Potter that has written several games and demos for the Dreamcast, including a commercially-sold game (''[[Feet of Fury]]'') and the most successful and widely-used homebrew software kit ''[[KallistiOS]]''. Megan Potter also developed [[libdream]], the first free development library for the Dreamcast. At the moment they are working on a Jump'n Run game called [[Donk: Samurai Duck]] ==September 2001 Interview with Megan Potter== This an interview with Megan Potter from [http://www.boob.co.uk B00B! Dreamcast Research]. It was taken on the 27th September, 2001 by Wraggster and was edited by [[TheGypsy]]. '''B00B! Dreamcast Research: Can you tell us where were you born, where you live, your family details, etc.?''' Megan Potter: I was born in Dallas, TX and lived there for 16 years until I moved out for college in Denton (also TX) and then Austin (again, TX). My dad's a geek of sorts himself, working as a machinist for engineers at design shops, and occasionally doing a bit of design work himself. His hobby now is making wind chimes and selling them at various weekend markets =). He's probably responsible in large part for me getting into computers and technology at all, I've got two older sisters who harrass me incessantly about how much of a geek I am. In a good natured way of course =). My step-mom's always asking when I'll strike it rich in my game development work so they can retire to Colorado but I suppose for the near future I'll have to keep saying "soon", hehe =) I have lived in Austin, TX since 1996, where I've been going to college. I recently lived in Tucson, AZ for 9 months and will move back there once I finish my degree. Can't beat the scenery, hiking/biking, amazingly dark sky for astronomy geeks, etc... just a great place. I guess Jessica (the girlfriend) moving back there helps to make that decision as well =) '''B00B: What qualifications do you have? What made you get into computers?''' DP: I'm kind of combining these two because they're quite related. Hmm... where do I start? (I did warn you about that head inflation thing ^_^;). When I was 4 years old, my father brought home a Speak and Spell from TI (where he was working at the time). Employee store, good discounts, etc. I think from that moment on it was too late for me to get interested in anything else for quite a while =). I got a TI-99/4A home computer when was 5 or so, and it grew from the simple console with Basic and Logo to a home computer workstation (lol). Basic console had extra RAM and a speech synth hacked into it, new cooler power supply, expansion box with a persistent RAM disk, two floppy drives, all those goodies! =D On that thing I learned 9900 assembly, and we bought a PC not too long after that. I guess it went from there: I spent most of my waking hours at school or on the computer. I wrote a tracker called "Farandole Composer" which some of you may remember with curses =). I participated somewhat as a side in the PC demo scene of the time, but we never really made much in the way of demos, and did a lot of talking. =\ Ah well, I got a few friends from that time. I had a BBS called Programmer's Oasis (it was 214-328-6142, if anyone remembers better by that =). I participated in a competition programming team in high school. It was a geeky high school (Science/Engineering Magnet) so we were like the football stars of the school. That was pretty damned cool, for a change =). I left there after two years to go to the Texas Academy of Math and Science, in Denton, where they shut you in a dorm with 399 other smart (and mischeivious) people for two years... man was that a riot! =) I got my high school diploma and two years of college there and moved to Austin, to finish a CS degree at UT. I'm still trying, but I've almost got it =). I'll stop there before I bore everyone, but suffice to say I've been sitting in front of a keyboard for a large part of my life since 5, and I'm 23 now. I've got a strong interest (probably thanks to school) in understanding computational science and how things _should_ work rather than just getting them working, but just kicking back and coding is quite enjoyable as well =) '''B00B: What projects/coding have you done previous to any Dreamcast programming? ''' DP: I listed a few above, but of interest to the DC community are of course the demos; I also worked on several (abortive) game project attempts with a friend of mine from Science/Engineering (hi Matt! =). These started with a simple overhead tile map and progressed over the years to a full Quake-style engine with source lighting and a custom scripting engine. Also of trivia value is that [[KallistiOS]]/DC was not the first incarnation of [[KallistiOS]]. Most people probably don't know this =). KOS was originally a project for the PC. I had a book called "Advanced 386 Programming" (I think that was it) that introduced me to protected mode, multitasking, etc. I had to sit down and write one =). I did all of that from that book and manuals I found on the net, so it proves you don't need a bunch of official devkit materials nor a degree to do this sort of thing. Just a keen interest and a lot of determination. '''B00B: What made you get into Dreamcast Development?.''' DP: It was almost an accident, quite literally. My roomate Phil invited us over to play Soul Calibur a long time ago, and I was so floored by the amazingness of that game (and obviously the system underneath it) that I added it to near the top of my "acquire when money arrives" list =). Soon after I bought the DC, they sent me an image for the CDX. Now, this was fantastic because I could play imports and all of that, but it got the gears turning in my head: if I can burn a normal CDR and run it on the DC with THEIR code, why not replace the code and burn my own anyway? I started hacking on the CDX and eventually found Marcus Comstedt's site. I didn't have a "[[Coder's cable]]" at the time so Tursi helped me out by running my test program and sending a screen shot. I got on the mailing list and started being more active with it, and a few weeks later I couldn't stand the suspense any longer: me and Jordan ordered the parts and built two cables, and I bought a SCSI CD-R to burn DC CDs with (since the one at work didn't do the job). Tursi and I worked on what was to become [[libdream]] for a little while, and eventually that did morph into [[libdream]]. I later got to discussing the idea with Jordan of writing a real embedded OS for the DC, and that was when [[KallistiOS]]/DC was born. It shares the name and some of the concepts of the original KOS/i386 but none of the code. Things just kind of went from there. '''B00B: Was [[Ghetto Pong]] a good learning step onto bigger things and how complex was it to code and get running nicely?''' DP: Oh yeah. [[Ghetto Pong]9 was Jordan's baby actually. He wanted to write a Pong clone for the DC just to play around with the coding aspects of it, so the original Ghetto Pong was actually just a red square moving across the screen with green block paddles. That's why it's "Ghetto"! =D I took that work of his and added menus, background music (thanks El Mobo! =), and sound effects, and his brother Kyle added some graphics. The result is the Ghetto Pong you see today. '''B00B: How did you start and what programs did you use to start coding?'' DP: I think I managed to answer this above during my lengthy discussion of my start with computing =). I'll add to it, though, that I used: * TI Basic, then * TI Logo, then * TI Extended Basic, then * TI 9900 assembler, then * GW Basic, then * Power Basic, then * Turbo Pascal for DOS, then * Turbo C for DOS, then * Watcom C for DOS, then * GCC for Linux That pretty much brings it up to modern =). I've had stints with Haskell, Python, Scheme, and a number of others that I don't use for "mainstream" work now. '''B00B: Tell us about your [[KallistiOS]] and [[libdream]] projects and did you have any idea that your work is looked on as the most significant piece of hobbyist software on the Dreamcast?''' DP: I guess I'll give an anecdote about [[KallistiOS]] that is kind of amusing, which I've talked about previously only in a translated Spanish interview. When we started KOS, we were trying to decide on a name. The original suggestion was actually "HuevOS", believe it or not. Our mascot was an egg, wearing a sombrero, and riding a surf board! (just consider all the puns for a minute =). Eventually, though, [[KallistiOS]] was chosen as the name because of the high interest among the authors in Discordianism =) I didn't know that it would eventually be looked upon as one of the most significant pieces of hobbyist software, when I started (or rather, when we started =). I guess it started the same way as any free software / open source project: there was a need to be filled, I wanted it filled, and I worked towards doing so. I guess the DC is complex enough that once there was a base and someone was working hard on it, no one else wanted to take the effort. The exceptions I know of are great work too, but they seem not to have caught on very much. I guess to me it became "truly significant" when I realized that people high up inside Sega were looking at it for more than a glance. =) Not for usage in anything official, just that they had added it to their map. Everyone on the dcdev list is probably familiar with this story though. '''B00B: What plans for the future do you have for KOS and KosWin?''' DP: I'll answer the second first since it's easiest =). I don't have any plans for KosWin because it was just something I did on a whim to try to help out some people who were having troubles. It seems on retrospect that the idea was well placed, but I'm kind of a fish out of water in the Windows world. ^_^; So I'm hoping other people will pick up the idea and go with it, and it seems that is happening. I'll be happy to host a good one on SourceForge's behalf (HEH). For KOS itself, I am basically hoping that it will grow to fill every need for hobbyists that was filled by Katana for official developers. This sounds a bit presumptuous, but I feel like we're already there to a large degree. I can't name any names, but a developer at SEGA told me once that my tools were easier to use than theirs for some things! With the addition of [[KGL]], an unencumbered MP3 player (working on it =), and the re-integration of things like lwIP and OS mode, it could go just about anywhere. I guess we'll just see what happens. '''B00B: What programs have helped you on the Dreamcast and how significant is a hardware OpenGL driver and to what programs/emus would be made accessible with it?''' DP: I guess as far as what _programs_ have helped, the major one has been dc-load and dc-load-ip. [[Marcus Comstedt]]'s tools have always come out as a sort of first pass to get people going, and then Andrew's tools come out and perfect the process. That has really helped things along. On the hardware OpenGL driver, be careful on terminology here. I'll be quick to point out (and so would SGI's lawyers! =) that what we have isn't an OpenGL implementation, but an OpenGL-like library. This is an important distinction, because I want to make GL programmers feel at home (and have something easier than raw TA for myself!). But it's not really OpenGL. I think the GL driver, though, is VERY significant. I didn't realize until I started using it myself just how convienent it is. With a few more mapping modes (e.g., ortho) and some glu functions, it could easily cut development time for DC things in half or more. I've definitely become a believer of GL at this point =) What could be made with it? Your imagination's the limit!(tm) Once lwIP gets re-integrated (and I've potentially got some SMB code coming from someone else) you could spend an afternoon writing an MP3 jukebox with fantastic visualizations. Games, demos, and even emulators. Who knows. The same things are possible that were before, they are just much easier. On emulators, I don't really know. I guess it's up to the emulator authors to be ingenious enough to use the 3D at all. This is not a simple problem since most earlier systems assume very low level control over the output (like SNES's HDMA). '''B00B: What programs/apps/emus would you most like to see come out on the Dreamcast?''' DP: I'm looking forward to JamDu coming out, if for no other reason than to see what came of that late-night inspiration almost a year ago =). Something else I always thought would be pretty nifty is a Dreamcast tracker. Why not?? You've got 64 channels of wave table sound, hardware accelerated 3D for any sort of inteface you want, a keyboard, a mouse, and space to save files (BBA, mainly). Even though Farandole was my last, I have still maintained an interest in trackers. Emulators.. I'd like to see a SNES emulator finished with full frame rate and sound quality. I'd love to pull out some old classic games and play them on a console again, since the original machines tend to decay and break over time. Beyond that, I'm always interested to see demos and games. Delicious was a very cool surprise that I've shown all my friends to say "here, this sort of thing is why I've been slaving over this box!" =) '''B00B: What's your opinion of the new super consoles like Xbox, Gamecube, Game Boy Advance, and the Playstation 2?''' DP: Oh man. You could fill a whole interview with this. =) But I'll refrain since I've got to run to class in about 15 minutes. *'''Xbox:''' Microsoft owns it, they're gonna do it wrong. I've seen some things on this machine that look VERY cool, like Jet Set Radio Future, and Dead or Alive 3. I've heard that the Microsoft titles are really looking up too, but the ones I saw at E3 were pretty disappointing. Guess time will tell. One thing I will say, it's HUGE. Way too big. For that reason alone it will probably fail in Japan. *'''Gamecube:''' Looks nifty, well put together, solid company behind it as usual. This will be a "safe" console to get for some fun games. The Star Wars game looked outstanding (again, at E3) but most of the others were not so super looking. Again, I guess time will tell. Integration with the GBA will definitely help the 'cube. *'''GBA:''' High on the cool factor, and it's great to have a real console to play a lot of old games being ported up. I'm guessing this thing hasn't even remotely been fully tapped for potential, and it's already got some amazing 3D-looking titles (like that tunnel game, can't remember the name now!), a DivX player (slow, but it's there), etc. *'''PS2:''' This is a really great machine processing power wise, but Sony has made the same mistake that they killed Sega for on the Saturn: the box has amazing processing capabilities, but it's extremely hard to code for. I don't even want to think about what they had to do to that thing to get GT3 out of it =). And I have to comment on one other aspect that always irritated me about it: whole lotta hype, normal amount of substance. Sony's PS2 marketing probably killed the DC, even though the majority of the released games for DC are far superior in game play and enjoyability to the PS2 titles out. This may change over time but I'm not keeping my hopes up. '''B00B: Which console looks the best for dev'ing on?''' DP: Still the DC. Except of course that your audience is quickly waning. I'd say next in line behind that are GBA and probably Xbox (it's a PC, it can't be that hard to get into =). Last I heard PS2 is still a major pain to dev for but this may improve in the near future. '''B00B: What are your favourite games for every system you have owned?''' DP: Ahh, well this one is easy! I've only owned two systems -- PS1 and DC. For PS1 I've like a lot of games on it, but I'd have to say one of the "good but unknown" titles is N2O. If you haven't played it, do so. It's cheap, and it's like concentrated Crystal Method (the band) stuffed into a game =) For DC, I basically haven't disliked any of the games =). They are almost all fantastic, at least the major ones. I've had a lot of fun with Evolution (3D Nethack, I like to call it), and a lot of team play fun with Phantasy Star. '''B00B: Your thoughts on the Dreamcast Emulation/Development Scene and how can it be improved?''' DP: I've probably said enough above already, but the one thing that could really help the scene is the one thing that's never gonna happen now: continued support for the hardware. I had glittery dreams of a hobbyist section in ODCM (which is now dead), some sort of hobbyist area on Sega's DC site (slowly dieing), who knows. That whole dialogue with John on the dcdev list was very promising. Suddenly, overnight, it became the "console that could have been". A truly regrettable state of affairs, but I guess a company's gotta do what it's gotta do to stay alive. At least Sega has continued making games! Their games have almost always been trend setters and it's good to see they will continue to be. See here, Tecmo already has a Space Channel 5 clone =). Anyway, I digress... '''B00B: Thank you for your time; it has been a honour for the scene.''' - wraggster ==2004 Interview with Megan Potter== This interview with [[Megan Potter]] was taken by [[MetaFox]] for the DreamOn magazine #1, which was released at the Midwest Gaming Classic in 2004. '''How did Cryptic Allusion begin?''' To start all the way at the beginning, I was going to do some web consulting for a company I was interning with for the summer in Dallas, TX. They advised me that tax-wise, I'd probably end up doing best if I formed a company to do the consulting through. My task then was to come up with a unique name that someone else wouldn't have already taken, and Cryptic Allusion was it. I'm still not 100% sure where those specific words came from, but that's what I came up with. Cryptic Allusion didn't do any more web consulting after that, and in fact it didn't do much of anything business related for a long time. It sort of morphed into a label for me plus any current group of friends that were working on something interesting. The membership of that group fluctuated over the years. During my years at the University of Texas, I was approached by a group of starry eyed game industry hopefuls trying to draft me into their game making effort. This included a number of people who are some of my best friends now, including Roddy. The original plan was to do a shooter type game for the PS2 (not quite out yet, at that time) and move on from there to an RPG project. We would get some basic stuff worked out and then hunt for funding, which was a pretty sound idea back in those days. The long and short of it is that after a very exciting start, the group more or less melted away. But I was too obsessed with the idea of starting a game company at that point, being as how it had also been my goal (little did they know) since I was about 6 years old. When I started getting into DC homebrew, I saw an opportunity arise for such a project. I emailed up Roddy and said: How would you like to work on this DC project? I probably can't pay you right now, but it might be a good way to get yourself out there. He responded back saying that he'd pay ME to work on a project, any project. Apparently Roddy felt the same way about all this game stuff. Our goal was to produce Tryptonite, the originally planned shooter game, for E3 and pass it out there as a way to get started. For various reasons we had some organizational and communication issues between ourselves and third party guys we'd pulled in to do parts of the game, so it was morphed into DC Tonic by executive decision about a month before E3. This turned out to be a good deal, as I believe DC Tonic still stands as one of the cornerstones of the DC homebrew scene's accomplishments. It also (along with some contacts of one of our members) got us into the invite-only Sega booth (score!) I'll continue this below in question 2... '''How did the idea for Feet of Fury materialize?''' After E3 we were sort of basking in the glow of the press and industry attention we'd attained with DC Tonic. We had also been infected by Dance Dance Revolution at A-Kon shortly after E3 (I use the word "infected" here because it's the most accurate -- once you catch DDR, you feel the compulsion to play day and night until it's out of your system a few years later). Roddy's a musician who makes some good dance/techno. The wheels started turning -- maybe there's some way we could put Roddy's music into DDR. I said, hey, I've got this nifty DC homebrew stuff sitting here, why don't I see what I can whip up? Well, the momentum generated there was a lot more than we expected. We were playing DDR and talking about the possibilities of making our own and such, and someone (can't remember who, might have been me) said, why should we make a DDR clone? Why don't we go way beyond DDR and make the game into something new and interesting instead of the same-old-same-old? We'd also been playing a real load of Puzzle Fighter, so the obvious idea was to combine the two and allow players to "attack" by throwing "arrow bombs" to the opponent when they were doing well. During our testing it became apparent that the idea of arrow bombs was not enough to make it more interesting than DDR. It needed more. A weird combination of "eureka!" and a mis-communication with one of our artists was what spawned the idea of having lots of different types of attacks. We knew we were on to something there and had to pursue it. Later on we realized also that if we actually finished this thing then we might be able to sell it and make money, and that meant a real business structure. So in November we filed for an LLC in Texas, and Cryptic Allusion, LLC was born as a "real" company at that point. All of FoF and all of our future productions are now under that banner. '''Every time Feet of Fury is shown at game shows it gets a rather large presence of people around it. Do you feel Feet of Fury stands up well in arcade like areas with the likes of DDR?''' Well, as you probably know, a creator of a work is never entirely pleased with the results. :) I think FoF could have been more than it is. Even so, ignoring the new features we've added that have made FoF a different game from DDR, I believe the "feel" of FoF is actually better. As a long time DDR player, I prefer to play FoF at this point, and given the self-criticism I mentioned above, I think that's a pretty important statement. I won't name any names, but we had some serious interest from a big-name company in an early publishing deal on FoF and they did some testing of the game with some of the DDR scene's biggest players. They were dubious at first but played for quite a while and liked it. I believe if we were able to go back and make FoF arcade machines with real, industrial-strength pads, and tons of music, we could take on DDR any day. Especially if people could bring their own Swap CDs to the arcade and play their own music, or arcades could provide their own Swap CDs to diffrentiate themselves from competing arcades (we had the competing arcades a lot in Austin). People love DDR but they are tired of Konami delivering the same game over and over with small tweaks in each edition, and increasingly annoying music. I know people who like the DDRMAX series, but most DDR people I know talk about the "good ol' days" of 4th and 5th mix. People are itching for something new and I'm sad that we can't provide that with our current operation. '''Is there anything that you wish Feet of Fury could have had if it had a bigger budget and a longer development cycle?''' I think Roddy covered this pretty well in his interview, but basically we would have liked to have had more music and better graphics (the part I worked on; our character artists were FANTASTIC). We would have liked to have actual animated characters with voice acting, acting out their fight in the background just like Puzzle Fighter or Puyo Puyo. We'd have loved to have an anime intro sequence encoded in high quality Ogg Theora. Most of all I would have liked more time to do several rounds of play testing to flesh out what works well and what doesn't in the gameplay. I think some of that is fairly rough still. I'm somewhat unhappy with the cleanliness of the code as well, but I ended up refactoring a lot of it about 10 times, which resulted in some nice free libraries like Parallax and Tsunami for all KOS users. It could have been a lot worse, so I think we did quite well within the constraints we had. '''How did you come up with the idea for the Typing of Fury mode?''' The real origins of ToF are somewhat apocryphal at this point -- I searched our email list archives and I honestly can't find the email that started it all, but I know the idea was first presented around the end of September a little after IGF. I think I originally proposed it. It's the sort of twisted thing that would come out of my head. Typing of Fury was one of those "nooooo freaking waaay" additions to the game that happened kind of late, but I'm very happy we included it because it's extremely original. It really sets us apart from the other rhythm games. As far as I know, no one has ever made a typing rhythm game before. I am actually happier with ToF than the main FoF "item battle" mode because we got to do a few rounds of tester feedback and improve the gameplay dramatically before it became a huge investment to redo it. As an aside, an excerpt from our mailing list that I can't avoid throwing in from my friend David, rejected announcer voice ideas: "YES, my PRECIOUSSSSS... DANSSSES IT DOESSSS, YESSSS!" '''What are your thoughts on the commercial future of the Dreamcast in the homebrew realm?''' There are some really fantastic possibilities there, but there are definitely some stumbling blocks. I think a lot of it's going to depend a great deal on whether people can feel good sticking with it instead of heading to the "next big thing". By that I mean, do you feel good continuing to make 100% legal and sellable games for a slightly dead system, or do you have to have the newest, like Xbox or PS2? And I think it depends too on whether people continue to buy new homebrew Dreamcast games even though the system isn't commercially produced anymore. I have actually been fairly baffled by the lack of interest in this so far, compared to bigger homebrew scenes, considering that authors are still making loads of cash on very old systems like the Vectrix and Atari 2600. I can tell you, anyone who is out there thinking about making a DC homebrew title, if you complete it and it looks professional, there are several people who'd be happy to publish it for you. The market is starting slowly and small but it is there. Another big stumbling block is one that is present in any sort of creative undertaking: deciding when enough's enough. A group of four guys plus a handful of outside musicians produced FoF in our free time, and it took us several years. And FoF isn't such an amazing product for several years' worth of work; we vastly underestimated the required effort. So many DC homebrew projects are started with HUGE ambitions like "create a full RPG". That's a really noble goal, but it's simply not possible, especially as a first project. I think DC Tonic and FoF were way beyond where Cryptic Allusion should have been at the time, and the only way we finished them was by putting in an incredible amount of obsessive effort, lost sleep and sanity, etc. Developers are going to need to get their teams going reliably and start kind of small. The most important thing is to _finish a project_. Your first completed project is not going to be a masterpiece; it doesn't have to be. The goal is to get momentum going for yourself and your team so that you can work up to greater and greater things, attract more talent, get contacts, and ultimately make that really awesome game you want to make. And hey, who knows, maybe you will have gotten enough attention then to get published on a still-active console. I urge anyone who's seriously interested in all of this to contact me at dpotter@cagames.com, and I'll be happy to discuss it with you. '''Do you think that shareware can work in the Dreamcast market?''' Absolutely. I believe shareware is the way to kickstart the DC homebrew market. I think that what we are really going to have to work on, to make it work right, is the delivery. There was an argument about this on our forums, but there are essentially two types of shareware: *1) Download and try a demo; if you like it, send money and you get a full professionally pressed CD and manual in the mail like a "real" game; *2) Download a limited version; if you like it, send money and they'll send you more levels, a code to unlock new areas, etc. The first one is easy, but it requires some manufacturing costs up front, which make it kind of less attractive for smaller developers (which still mostly includes us). FoF is proof that the first option is quite feasible if you have some investment. What you really want for kickstarting the market is the second option, so people can sell little one-off puzzle and fighting games for $5 a pop or something. These make great impulse buys, and you're supporting the game makers you like directly. The problem there is that the decent communications peripherals for the DC are rare, and there was no real persistent storage produced. So you'd need a very reliable and uniform way to burn the games to a CDR on a PC. And as we probably all know, that just hasn't happened. What it's going to have to happen is that someone needs to make a delivery mechanism that is extremely easy and transparent to use for buying the games and burning these games to the customer's CDRs. Self-Boot Inducer (SBI) and Dream Inducer (DI) are a great start there, but I think there needs to be a more polished and integrated package to handle the whole task, and it needs to support all platforms (PC, Mac, Linux). Ideally something along the lines of iTunes(tm), but for DC games: browse the store, check out preview videos (and maybe demo versions), add the games you like to your cart, and then check out to get your "game bundles". Insert a CD and select the games you want on it, and tell it to burn. Out pops a bootable CD with a professional quality selection menu (or no menu perhaps if the user only burned one game to the disc). Once you have such a system, the "option #1" games will follow as the most popular authors get a following and earn enough money to fund better games and manufacturing. '''Any insight towards what Cryptic Allusion has planned for the future?''' First and foremost, we are planning to continue to make DC homebrew titles for as long as we can stand it. :) Another project is now in the works which will probably be announced officially by the time this magazine is published. Second, I am going to continue to maintain and improve KallistiOS for the community as long as I can, and through me CA will be contributing a lot of code to the community from our projects. Numerous improvements to KOS which have become quite important to the community now (such as the new PVR system, KGL, and the new Maple system) were started so that we could write FoF. Much code has been contributed directly from FoF as well, such as the Parallax and Tsunami libraries. We plan to continue this trend with future projects and eventually release the full sources for all of our game projects under a free license somewhat like ID with the old Wolf, Doom, etc. Third, we plan to continue our market building strategies for the DC homebrew community. This involves making and selling more games of our own, and perhaps some of the infrastructure support for the shareware model I mentioned above. I'm convinced that approach would make things really take off, and I'd like to help jumpstart it. 919308d06f4b60474ede9c1db36c1d493e540861 ReGex 0 1024 2933 2222 2023-04-01T19:25:49Z Unknown user 0 wikitext text/x-wiki [[Image:catandc.jpg|thumb|CatanDC]] ReGex was Dreamcast programmer. He released [[FrNES]], a good NES emulator, and was working on [[CatanDC]], a Dreamcast implementation of the popular German board game "The Settlers of Catan" ("Die Siedler von Catan") but never released it due to data loss after he moved to a new city. In 2004 he sent out an email: ''Hey Sander, ''I thought I would let it die for a number of reasons. About a year ago when I moved I suffered a *big* data loss, 1 whole HD containing my entire development environment, and the current version of the CatanDC source (the last archive I had was from months before, lots of the engine was lost and I was so frustrated that I didn't even want to look at the website or anything anymore.. and just leave it as it was). That's the end of the story,really. I just was so frustrated that I didn't have the will to redo all the parts I'd lost (which were the really advanced features like Multi-VMU and the actual game engine.). ''Thanks for your interest, and at some point I may consider releasing whatever source I had built.. I just don't feel like digging it up and reliving the upsetness I feel towards the project at the moment. ''-Matt Alex (ReGex) ==Links== *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=5139 ReGex' profile on DCEmulation] *[http://archives.dcemulation.org/ReGex/ ReGex Web Presence (Archived)] This is an interview with [[ReGex]] that was done in 2001 by Wraggster. '''DCEmulation: Can you tell us about yourself and where you are from and what's your job, school etc?''' ReGex: I'm 22 years old, and I've been living in Calgary, Alberta Canada my whole life. I'm a Mechanical Engineer, and I graduated from the University of Calgary last year with a BSc.. I'm currently working on my Master's degree in Design Engineering. I am currently writing a conference paper, and my thesis. I help teach a couple courses at the university (mechanical simulation and artificial intelligence). '''DCEmulation: How long have you been into computers and more specifically coding? [Beware... long answer]''' ReGex: I started programming around the mid 80's when I was a little kid. I'd always been interested in robots and spaceships and stuff from the movies, and my Dad told me all about computers and that, because he's a Mechanical Engineer (and an accomplished programmer) as well. My Dad gave me some books on how to program, and some of those old books with code listings you could type out to get these little BASIC games to play. I did that up until I was about 12 and lost interest in it (I was much happier to play my NES). I stayed out of serious programming until around 1994 (although I did a bunch of little projects along the way), because there was a resurgance of interest for me when I got into the Demo Scene. I took Computer Science in High School (with a great teacher, Helen Koch) and learned Turbo Pascal. Between getting into demos and learning compsci, I joined a local demo group called Skyfire, and we started doing intros and stuff for our BBS. When I graduated High School, our group broke up and I focused on school. I got really good summer work (from the best boss I could have had, Doug Slack) at an oil company doing some little apps for Windows, and I cleaned up my C/C++/Win32 skills there. I also read Michael Abrash's books at that time, which are really good if you're interested in learning how to code hardware level graphics (at least in a pre-accelerator context). I also worked for a commercial software company, Objectworks, for a summer. Now I am developing software to accompany my thesis, and of course my DC projects. '''DCEmulation: What made you choose the Nes and the PcEngine To Emulate?''' ReGex: I really love both the systems... perhaps the NES a little more than the TG/PCE. I actually wanted to do the port of Hu-Go first (because I want to play Blazing Lazers on my DC), and have *technically* been working on it since November. I wanted to do the NES, because the system is really cool, and also that progress on the port of Hu-Go was going *so* slowly... mostly because of my own inexperience with embedded hardware. '''DCEmulation: What problems have you had and how did you overcome then?''' ReGex: Sound was *really* hard to do for [[FrNES]]. It was funny that [[NesterDC]] 3.0 released like the day after I got sound working, after I'd put all that work into doing it myself. To get through it, I just sat down for 2 weeks, warmed up the ol' coder's cable and debugged for 4-5 hours a night. Add some Slinky + Ninja Tune CDs to the mix and you have the recipe for success. '''DCEmulation: With 2 more emus being written for the Nintendo Entertainment System and up to 3 being written for the PcEngine has that made you more determined to complete your project and also have you teamed up to overcome problems that have been halting your progress?''' ReGex: Determination is in short supply over here :D My work requires me to use most of my quality brain-time there, so it's rare that when I come home, I'm all psyched to code. I would like to see my projects all be finished well, before too long (it would be nice before the end of 2001) but I'm not promising anything. Other emu's are somewhat of a concern, admittedly, but most of the projects I do are for my own enjoyment first, so I don't care *that* much if someone releases before I do. There has been a fair amount of code sharing going on between myself and other devvers in #dcdev. '''DCEmulation: When youve reached the end for this project, do you have any new projects in mind?''' ReGex: Well, when I'm done both FrNES and the TG/PCE emu, I might like to help out on some other project... I'd like to help out on something like crt0's OpenGL stuff... My brother and I have a top secret homebrew game in development, but it's not ready to be talked about yet. '''DCEmulation: What is your favourite Dreamcast emulator?''' ReGex: I'd have to say Bleem GT2, because I've logged more hours with that than I probably should have (took a week away from [[FrNES]] 0.50 :D)... I really like [[DreamSNES]]. I use [[FrNES]] a lot (even though I'm a little biased). '''DCEmulation: What is your favourite game for The Nes and also the PcEngine?''' ReGex: I'd have to say Contra on the NES, and Blazing Lazers on the PCE. '''DCEmulation: What is your opinion of the Dreamcast Scene, DCEmulation, and what would you do to improve it to make it more accessible?''' ReGex: I think the DC scene may have shrunk recently, but I don't really mind. Some of that shrinking might be due to Selfbootbuddy (and that everyone is burning their selfboots on the first try.. and not bothering people in the forums...but that's just my theory :D). I think Megan Potter and her group are doing fantastic work (without which I wouldn't have been able to do mine), and they are keeping things alive. Their work is indispensible and really superior. Dcemulation is a good gateway, and I always go there to check for news and stuff... I think improving updates on a daily basis would definitely help bring more people in on a regular basis. I like the idea of tournaments and stuff with DCE... I haven't played Q3A in a while :D '''DCEmulation: What is your view on the other new super consoles and the possibilitys of hobbyist development on them ie gba etc?''' ReGex: GBA is cool... I have one myself, and would love to do some coding on it. (Check out Loopy's version of his NES emu for GBA.. it's super sweet!). Gamecube looks cool,. but I'll suspend judgement until someone figures out a programming backdoor. PS2 is a maybe (until there's a way of stably getting one modded for development, I wouldn't consider it). '''DCEmulation: May I say thank you for your time and good luck with your project on behalf of DCEmulation and the rest of the emulation scene.''' Regex: Thanks Wraggster, always a pleasure. 5f8869c635edcc3f1912895adfdb1f457afada00 TheGypsy 0 1021 2934 2218 2023-04-01T19:26:11Z Unknown user 0 wikitext text/x-wiki TheGypsy was a Dreamcast programmer. He released [[GypPlay]], one of the best media players for the Dreamcast. He is also known for hosting [[B00B! Dreamcast Research]], which was one of the biggest Dreamcast sites from 2000 until 2004. We have done an [[Interviews:TheGypsy|interview]] with TheGypsy. *[http://www.thegypsy.com TheGypsy.com] *[http://www.boob.co.uk B00B! Dreamcast Research] *[http://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=7109 TheGypsy's profile on DCEmulation] This interview with [[TheGypsy]] was taken by Maturion on April 22, 2008. '''Why did you release GypPlay, what kind of problems have you had and how did you overcome them?''' I wrote GypPlay simply because I thought it would be interesting and fun to work on something for the Dreamcast. I had previous Windows coding experience, so the availability of the WinCE libraries on the Dreamcast made the learning curve much more gradual for me than would have been the case for non-WinCE development. Of course, one of the problems was simply lack of available details related specifically to the Dreamcast. I had some access to the leaked "official" devkit documentation, but even that was light on detailed information. There was some decent sample code, but most of it was very specific to one particular feature that they were trying to demo in that code snippet. Therefore, doing any real application that was complete still took a great deal of "guess and check" sort of development. Of course, that directly related to the second big problem: lack of any real development hardware. Developing for the Dreamcast at that early stage meant burning a lot of CDRs for testing. I probably went through 70-80 CDRs before I finally took the time to modify my Dreamcast to be able to read CDRWs. Also, at that time, a disc swap was required to boot the discs, so it put a lot of wear and tear on my Dreamcasts. I had one that I kept almost completely dismantled the entire time during development so that I could more easily do disc swaps and other such things. Later, the Utopia Boot Disc was released which did make development a bit easier (although it also opened up the world of game piracy that I was not overly fond of). If I recall, the first version did not work for booting WinCE-based discs, so it wasn't until a later boot disc release that I could actually make use of it to aid in development of GypPlay. '''How long did it take you to release GypPlay?''' I actually looked back through all of my notes and emails from that time period and was unable to determine exactly when I started development of GypPlay. I first started working on a WinCE boot loader that was intended to be used to download applications via a serial cable for testing. In the middle of that, I started with on GypPlay. My guess would be that I worked on it for around three weeks to a month before v1.0 was released about 3am on August 14, 2000. v1.1 followed about 12 hours later on the same day. '''Have you done anything else than GypPlay for the Dreamcast?''' I actually did some work on [[Boob!boy]], which was [[CyRUS64|CyRUS]]'s Gameboy emulator for the Dreamcast. To be honest, I have never been a big fan of emulators, so I did not want my name associated with it at the time. [[CyRUS64|CyRUS]] was having some trouble getting the controls to work smoothly, so I rewrote most of the controller code. I then asked him to not mention me helping with it. I should probably explain myself a bit about emulators since I know that they are very popular and stating that I am not a fan of them might not go over well. I'm actually a bit of a "purist" when it comes to certain video games. I actually collect the classic full-sized standup arcade games. I can't help but see things such as MAME actually hurting those old classics. Because of MAME, there are less people interesting in collecting the original machines. Granted, I understand that a lot more people can PLAY those old games now -- which I do see as a good thing -- but there is a price to be paid for that easy accessibility. Therefore, I've simply never been a big fan of emulation except in some rare circumstances. That being said, I will admit that I've become a bit of a hypocrite in that regard over the years. If I want to play a quick game of Mappy or Galaga, it is just easier to plug some current console into my HDTV upstairs and just starting playing than to go into the basement and try to fire up the actual arcade machine. But, now and then, I still do it just for that classic experience. '''How was the feedback of the scene to [[GypPlay]]?''' Initial response from most people was excellent. The ability to easily play MPEG video from the Dreamcast and have it be relatively smooth and stable was something that a lot of people were very interested in. That, of course, was mainly from an end-user standpoint though. From within the development community, there was some backlash from people that would prefer that no SEGA or Microsoft libraries be used. Of course, I would have preferred that too but, at the time, I simply couldn't have done it without using those libraries. Non-official SDK based information was scarce and just beginning to be discovered. Plus, I did have a "real job" that I needed to attend to, so my time was limited. In the end, I made friends with many of the ongoing homebrew Dreamcast coders and long-term feedback about GypPlay seemed to remain encouraging from both them and the end-users. '''Did SEGA ever try to contact you?''' I actually made the first move and contacted SEGA. After [[GypPlay]] had been released to the public and was getting quite popular, I started to worry a bit that it might have developed a large enough following that SEGA or Microsoft would take an interest and pursue legal action against me for distributing some of their libraries needed to use it. I found a post from John Byrd, who was the Director of Development Technology for SEGA at that time. I sent him an email from my real email address telling him that I was the author of GypPlay and asking if SEGA would be willing to discuss some sort of licensing agreement so that a hobbyist release like GypPlay could be distributed without legal issues. While working out the distribution rights would be difficult, they at least wanted to get me legal as far as having access to the SDKs was concerned. So, they sent me the paperwork that included the SEGA NDA (Non-Disclosure Agreement) and Developer Tools Agreements from SEGA and M icrosoft. They signed me up as an official independent Dreamcast developer. As far as I know, I was the only such person registered that way. This was in late September of 2000. SEGA stated that they were working on a "kind of hybrid open-source license" that would allow hobbyist developers to release software such as GypPlay. Unfortunately, this never came to be. Microsoft had released information regarding the XBox by this point, which meant that SEGA had very little pull with them to try to encourage additional development on their competing hardware -- especially for open-source hobbyist projects that would make neither company any actual money. In any case, it took several months to get all of the paperwork taken care of. SEGA of America had to send all of the Developer paperwork to SEGA of Japan and to Microsoft to be signed. So, by the time everything was done and I was an "official" developer, it was January. I was then given access to SEGA's developer web site and their developer tools ordering system. I didn't have a lot of money at the time, so all I ever bought were a few DC mice to experiment with. Unfortunately, over the next six months, things fell apart at SEGA as far as Dreamcast development was concerned. John Byrd, my original contact, and most of the others had been terminated or otherwise left that part of SEGA. By July, there was officially no longer any engineering support from SEGA for the Dreamcast. I attempted to see if I might be able to get some of the leftover development hardware to continue and SEGA did make an attempt to do this, but the details could not be worked out before everything related to DC development was terminated. A few months later, even the official developer web site was closed. '''Why have you stopped developping (or at least releasing) new versions of [[GypPlay]]?''' Mainly lack of time. Plus, since no legal agreement could ever be arranged to be able to release a licensed version of [[GypPlay]], it meant that any future releases would also technically be violating the law. I was no longer in a place in my life that I wanted to risk that on an ongoing basis. Plus, I had won Lik-Sang's "[[y2kode]]" competition -- which included a free trip to Hong Kong for a week! That was really the culmination of everything related to GypPlay. I had done my best at the time, released that final version, and just felt that it would be best to move onto other projects (none of which were Dreamcast related). '''What do you think about the Dreamcast scene now?''' To be honest, I haven't followed much for the past few years. While I loved the platform itself, I can't help but feel that it is mainly past its prime even for homebrew development. There just aren't enough end-users left to appreciate an author's work. Someone could release an excellent game or application for the Dreamcast today and there simply wouldn't be enough people around to really use it. There is still a great cult following, of course, but nothing like those glory days when you could release something and see hundreds of downloads that very first afternoon and thousands over the next few days. '''Do you plan to return to the scene one day and maybe release a new [[GypPlay]] version?''' This would be very unlikely. Life just happens and people find that they have other things that they would like to do. Now and then, I like to dabble in some console development just to see what is out there, but it is not something that I dedicate a great deal of time to any more. I really had a great time working with the Dreamcast and with the many people that contributed a great deal to make homebrew development possible (Megan Potter and Marcus Comstedt immediately come to mind), but most of us have since moved on and will have to simply rely on our fond memories of the machine. '''I would like to thank [[TheGypsy]] for this nice interview!''' 80a24c5631a2db3d9a85ad159d2cda2ecc1fd573 GCC-SH4 tips 0 165 2935 958 2023-04-01T19:26:41Z Unknown user 0 wikitext text/x-wiki These notes is mostly taken from the good advice of all the Dreamcast scholars (Ian Micheal, Moop, MrNeo, and more). The original documents can be found [here.](https://dreamcast.wiki/wiki/images/f/f6/Gcc_asm_sh4_tips.txt) ==Megan Potter's GCC-SH4 tips== ===Use local variables=== Global variables are slow - to retrieve the value, the SH4 typically must execute: <syntaxhighlight lang="asm"> mov.l L2,r1 mov.l @r1,r1 </syntaxhighlight> Local variables are faster - it's stack-relative, and '''function parameters are even faster because the first four integers parameters are passed in R4-R7 and first eight floating-point parameters in FR4-FR11'''.<ref>''[https://gcc-renesas.com/manuals/SH-ABI-Specification.html]'', SH ABI(Application Binary Interface) for GCC</ref> ===Write small functions=== We've noticed GCC generates very pessimal code when it starts to spill registers, so try to avoid doing too much in one function. A function which exceeds more than about a hundred lines should be broken into smaller functions. ===Use struct copies (instead of copying individual elements of a struct)=== GCC and G++ generate code with weak scheduling when copying a struct by individual elements. GCC and G++ generate code with better instruction scheduling when copying a struct via struct assignment. == Division == Using division on the Dreamcast is very costly. Division('''fdiv''') takes ~13 cycles.<ref name="sh4asm">''[http://www.shared-ptr.com/sh_insns.html]'', SH4 Assembly Instructions</ref> === Integer === If you're using integer and want to divide by a power of two, you're better off using bit shifting. (Note: GCC does this conversion automatically, and has done so for at least 10 years now, so you don't need to worry about it) <syntaxhighlight lang="asm"> int result = var1 >> 1; //is the same as var1 / 2 but way faster int result = var1 >> 2; // = var1 / 4 int result = var1 >> 3; // = var1 / 8 </syntaxhighlight> === Float === If you're using float, transforming your division into a multiplication is also faster. Multiplication('''fmul''') only takes ~3 cycles.<ref name="sh4asm"/> <syntaxhighlight lang="asm"> float result = var1 * 0.5; // same as / 2 but way faster float result = var1 * 0.25; // same as / 4 but way faster float result = var1 * 0.1; // same as / 10 but way faster </syntaxhighlight> ==References== <references/> b7e8f2b9e8054d771ad024ec49ac5dae32fa1d42 Dreamcast emulators 0 4 2937 2687 2023-04-01T19:28:39Z Unknown user 0 wikitext text/x-wiki Emulators can be very handy when you want to test code quickly, but can't be totally relied on. Some emulator are closer to the original console while some will run your game even if a real Dreamcast can't. ==Reicast == *Official page: [https://reicast.com] *Developed by: skmp, others. Derived from nullDC. *Status: Active, Under rewrite *Platform: Android, Windows, Linux, macOS, html5 ===Supported features=== ===Known issues=== *Extremely buggy ==Redream== *Official page: [https://redream.io] *Developed by: inolen *Status: Active *Platform: Android, Windows, Linux, macOS ===Supported feature=== ===Known issues=== *No sound support for homebrew with HLE bios ==NullDC== *Official page: [https://github.com/skmp/nulldc] *Developed by: skmp, ZeZu, PsyMan *Status: Inactive *Platform: Windows ===Supported feature=== ===Known issues=== ==lxdream== *Official page: [http://www.lxdream.org/news/] *Developed by: nkeynes *Status: Inactive *Platform: Linux and macOS ===Supported feature=== -'''DEV''' Console support (printf) ===Known issues=== ==lxdream-nitro== *Official page: [https://gitlab.com/simulant/community/lxdream-nitro] *Platform: Linux and macOS *A community-improved version of lxdream ==Demul== *Official page: [http://demul.emulation64.com/] *Developed by: Wind, CaH4e3, ajax16384, DreamZzz, MetalliC *Status: Inactive *Platform: Windows ===Supported feature=== *MMU, Naomi 2 ===Known issues=== ==WashingtonDC== *Official page: [http://washemu.org/] *Developed by: snickerbockers *Status: Active *Platform: Linux, Windows ===Supported feature=== *Console support (printf) via serial port *remote GDB debugging ===Known issues=== *game compatibility *Z-Fighting ==MAME== *Official page: [http://mamedev.org/] *Developed by: MAME community *Status: Active *Platform: Linux, Windows ===Supported feature=== ===Known issues=== *game compatibility *speed ==Other older emulators== These emulators are listed mostly for historical/archival reasons. ===Chankast=== *Chankast is a Dreamcast emulator for Windows. Released on May 29th, 2004, Chankast was the first publicly-released Dreamcast emulator to play commercial games playably. It is now considered outdated. *Authors: baktery, unai and garrofi *[http://www.chanka.org/ Homepage] *Latest version: Alpha 0.25, 07/07/2004 ===Makaron=== *Makaron [[File:Swirly.jpg|thumb|Swirly running Megan Potter's Stars demo]] ===DreamEmu=== [[File:Dreamemu-01.jpg|thumb|DreamEmu running DC Space Invaders]] * Developed by Lord Cheese, DreamEmu is an early Dreamcast emulator that can only run some tech demos and homebrew, last released on 10/28/02. * Downloads: [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-0.0.4.1-bin-rel.zip 0.0.4.1], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-003.zip v0.03 - 08/03/01], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu-002.zip v0.02], [https://files.dcemulation.org/software/dcemulators/dreamemu/dreamemu_001a.zip v0.01a] * [http://www.dreamemu.net/ Homepage] ===Dreamer=== *Developed by ElSemi in late 2000 into mid-2001, Dreamer was the first working and released Dreamcast emulator for PC. *Latest version: Alpha 0.25 - Download [https://files.dcemulation.org/software/dcemulators/dreamer/dreamer002.zip v0.02] *[Dreamer](http://emulatronia.com/dcemu.htm) *SH4: All opcodes is emulated (100% have not been proven) interprets. Those of movements of data to memory and jumps are emulated using dynamic recompilación. *FPU: All opcodes emulated for want of the 2 specific instructions of the Dreamcast. > uses the interpreter - Slow. *PowerVR: The basic part of the hardware 2d works (Framebuffer correctly and control registries). It lacks the way of video 555. We are at the moment looking for information on the hardware 3d and display lists. *JoyPad: Emulated completely. *Maple Bus: The control registries have been identified and will be working shortly. *Sound: Nothing yet. *CDROM: Almost emulated. *DEBUGGER: The emulator takes integrated to debugger (that is a little patatero but it plays his role). Executing debugger implies that the execution of the program is much more slow. The handling keys are the following ones: *F5: Go (uninterrupted Execution)<br/> *F7: Draw up Into (to execute entering the subroutines)<br/> *F8: Step Over (To execute without entering the subroutines, does not work to 100%) *Commandos: The commandos are written in the inferior part of the window of the code:<br/> **G (Just as F5)<br/> **G direction (Executes until that direcci¢n. in hex)<br/> **D direction (shows the memory of the specified direction. in hex)<br/> **D registry (it shows the memory of the direction loaded in the chosen registry)<br/> **And direction data (writes in the direction the specified data. 0-FF in hex)<br/> **R registry value (loads the value in the registry. 0-FFFFFFFF in hex)<br/> **S (it stops the single emulation works in Go way)<br/> **F (it draws framebuffer)<br/> **X (to leave)<br/> **Z (reset, cracks, not to use)<br/> **WD 0|1 (oculta|muestra window of data)<br/> **WR 0|1 (oculta|muestra window of registries)<br/> **WM 0|1 (oculta|muestra window of messages)<br/> **WC 0|1 (oculta|muestra code window, nor is happened to you, but where you write) ===Swirly=== *[Swirly](http://swirly.sourceforge.net/) 074f702e93ad9e4b5e1650c8aeecd31386cf0152 Libronin 0 167 2938 1881 2023-04-06T15:02:45Z Unknown user 0 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to ensure raw toolchain with no patches Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. '''Do not''' use <code>make</code> alone or the build script will patch the toolchain with KOS patches, which is not what we want here! make build You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 0c028b291fde157f11402b6d7914fdb2f5a961e5 2939 2938 2023-04-06T15:02:57Z Unknown user 0 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to ensure raw toolchain with no patches Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. '''Do not''' use <code>make</code> alone or the build script will patch the toolchain with KOS patches, which is not what we want here! make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} ae095f3b1a814c66d17126cf3de034a124d375fc 2940 2939 2023-04-06T15:04:40Z Unknown user 0 wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to skip copying KOS headers into toolchain auto_fixup_sh4_newlib=0 # Set this 0 to ensure raw toolchain with no patches Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 3e93a9b268b0aeb11d716d29edc092cda7764964 2941 2940 2023-04-06T15:05:13Z Unknown user 0 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to skip copying KOS headers into toolchain Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} b62231bdf7d154133f54922822182364ef53d66f 2942 2941 2023-04-06T15:05:42Z Unknown user 0 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to skip copying KOS Newlib headers into toolchain Download the packages: ./download.sh Unpack the files: ./unpack.sh And finally, build the toolchain. make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 82ec1b614c9a60782856c34e0faa4a684482c246 Maple bus 0 113 2943 1875 2023-04-19T22:03:00Z Unknown user 0 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a normal start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 5fb31c950a94286d15d7d75255389c6e34f2aeec Hardware overview 0 38 2944 731 2023-04-19T23:24:16Z Unknown user 0 wikitext text/x-wiki *'''CPU''': Hitachi SuperH SH7750 SH-4 RISC CPU @ 200MHz **200 MHz/360 MIPS at 3.3V I/O, 1.8V internal **16 x 32-bit general purpose registers **32 x 32-bit single-precision floating point registers **16-bit fixed instruction length for high code density **5 stage pipeline **On-chip cache, 8KB instruction and 16KB data *'''GPU''': NEC PowerVR2 with 8MB of [[VRAM|texture memory]] *'''Sound''': ARM7DI-based Yamaha AICA (64 channel PCM sound) with 2MB memory *'''Memory''': 16MB system memory *'''Storage''': [[GD-ROM drive]] *'''Network''': 33.6K or 56K [[Modem|modem]] [[:File:150-000105-1e SegaDreamcast.pdf|Sega Dreamcast Electronic Game Performance and Design Analysis by Portelligent]] 589a970b85346b30c5026100ebe66e7a2a1467b2 Getting Started with Dreamcast development 0 694 2945 2566 2023-04-26T14:39:19Z Unknown user 0 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 12.2''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 68b91f0c720fcfc0f6424b56b53f586379a94976 2946 2945 2023-04-26T14:39:27Z Unknown user 0 /* Compiling the toolchain */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb '''Important Note for Apple users''': If you chose '''GCC 13.1''', you will need to export a few paths before running the above command or else building GDB will fail: Intel Mac: export CPATH=/usr/local/include export LIBRARY_PATH=/usr/local/lib Apple Silicon: export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. b35787e3b8453c1abfb7ffbb851321dcc628890b 2947 2946 2023-04-27T06:18:38Z Unknown user 0 /* Compiling the toolchain */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. f8d1b722754675eee4bdbb9e7578d71d7208b485 Twiddling 0 1375 2948 2023-05-13T13:19:24Z Unknown user 0 My write up of the explanation of twiddling an image and converting the indexes back wikitext text/x-wiki How to generated the twiddled index from an untwiddled texture Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 90de3c650681bdc4902a7509e712f388849fe630 Twiddling 0 1375 2949 2948 2023-05-14T03:38:29Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Axised curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Dreamcast Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] dd06b2e154527cee41a181d5cf163c5affab435e 2950 2949 2023-05-14T03:40:11Z Unknown user 0 /* General Idea */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Axised curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the texel index. Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Dreamcast Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 0efc5910930110fc43db72d29531eb29067b6051 2951 2950 2023-05-14T03:40:55Z Unknown user 0 /* General Idea */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Axised curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the texel index. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Dreamcast Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 7690140d764aa1a31861a32f0effbe435cac1b71 2952 2951 2023-05-14T03:58:30Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Axised curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Axis position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { if (b % 10 != 0) { result += a * (b % 10) * multiplier; } b /= 10; multiplier *= 10; } return result; } == Look-up Table == == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 6c20b08fa31814af27e4da8a9729002834f68462 2953 2952 2023-05-14T04:02:35Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Axised curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Axis position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { if (b % 10 != 0) { result += a * (b % 10) * multiplier; } b /= 10; multiplier *= 10; } return result; } == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 29e8f3d6ac807017340d2dac61c47da1105511cb 2954 2953 2023-05-14T04:05:33Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { if (b % 10 != 0) { result += a * (b % 10) * multiplier; } b /= 10; multiplier *= 10; } return result; } == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] b36cbfb8c8f59bdbb44e763bffeff5853df2b0ea 2955 2954 2023-05-14T04:09:39Z Unknown user 0 fixing errors wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: { int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { if (b % 10 != 0) { result += a * (b % 10) * multiplier; } b /= 10; multiplier *= 10; } return result; } } == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] bc2a652e99be968930567993a2a8ddd2935ec357 2956 2955 2023-05-14T04:17:40Z Unknown user 0 /* Bit-twiddling Implementations */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { if (b % 10 != 0) { result += a * (b % 10) * multiplier; } b /= 10; multiplier *= 10; } return result; } == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 4100ebbafd2ca532282e2bfb86526206fa6e1866 2957 2956 2023-05-14T04:18:15Z Unknown user 0 /* Bit-twiddling Implementations */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { if (b % 10 != 0) { result += a * (b % 10) * multiplier; } b /= 10; multiplier *= 10; } return result; } == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] f337ebbc30b55da2e4a74a0b186aa90c5f4d03e7 2958 2957 2023-05-14T04:21:50Z Unknown user 0 /* Bit-twiddling Implementations */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Implementations == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 916bf821928958fbbd0f24930d31c5f809d3ac97 2959 2958 2023-05-14T04:22:03Z Unknown user 0 /* Non-Dreamcast Bit-twiddling Implementations */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 24b171931e0f11963800e9d0fd833b409f2c3acc 2960 2959 2023-05-14T04:22:54Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (16-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: ``` '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } ``` In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] e829036c336ff5d9f23765563f9a9649ef317de0 2961 2960 2023-05-14T04:24:08Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: ``` '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } ``` In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. // x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] c8241921954a64567dd6b5245695afb8eb275d91 2962 2961 2023-05-14T04:33:30Z Unknown user 0 /* Binary Magic Numbers Implementation */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: ``` '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } ``` In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. [code] static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); [/code] == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 9d28e8ad86fb895c8f82cac8325e931eec17499d 2963 2962 2023-05-14T04:35:13Z Unknown user 0 /* Look-up Table Implementation */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: ``` Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + ``` The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: ---------- i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F ---------- Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: ---------- i == 0 0 2 1 3 ---------- You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: ``` '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } ``` In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. [code] static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); [/code] == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 0d386953a114ed4da068b631289bdf10d5b67bc2 2964 2963 2023-05-14T05:00:12Z Unknown user 0 /* Protofall's Implementation */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: ``` '''int multiplyWithoutCarry(int a, int b)''' { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; } ``` In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. [code] static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); [/code] == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] ec807cb6372a3d463898449e6307e4147176f410 2965 2964 2023-05-14T05:02:23Z Unknown user 0 /* Non-Dreamcast Bit-twiddling Hacks */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. [code] static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1); [/code] == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 925536ff9f04198aea9160f3afebef4e98b98372 2966 2965 2023-05-14T05:03:27Z Unknown user 0 /* Binary Magic Numbers Implementation */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF]; For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 03af94123951abdfa87f9deeab28cf4d8ed628c5 2967 2966 2023-05-14T05:04:02Z Unknown user 0 /* Look-up Table Implementation */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: * top left quadrant is '''0''' * top right quad is '''BOIN-width / 2''' * bottom left is '''BOIN-width * (BOIN-height / 2)''' * bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF];</syntaxhighlight> For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] 75b7d16df58d4e3ccfbd655b11453ec40a0f6b30 2968 2967 2023-05-14T05:07:56Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: ** top left quadrant is '''0''' ** top right quad is '''BOIN-width / 2''' ** bottom left is '''BOIN-width * (BOIN-height / 2)''' ** bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == Non-Dreamcast Bit-twiddling Hacks == A problem withe morton encoding is that it's an expensive operation normally unless attacked in the right way. It's usually far too costly to navigate a twiddled image every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation. On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. But that's not useful for Dreamcast programming. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied without carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. However, the Dreamcast does not have a multiply-without-carry function, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> In this updated version, the /= 2 division operation has been replaced with bit shifting. The divisor and tempMultiplier variables are shifted left (<<) and right (>>) by 1 to perform the division or multiplication by 2. == Look-up Table Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF];</syntaxhighlight> For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Implementation == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] d88680727481024df1142f7c68d035bd0214430d 2970 2968 2023-05-14T06:19:18Z Unknown user 0 wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. A problem with using Z-ordered curves is that it's expensive to compute every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation, covered below. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Look-up Table Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF];</syntaxhighlight> For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == Non-Dreamcast Bit-twiddling Hacks == On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. As the Dreamcast lacks these instructions, this is not a viable dreamcast solution. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied-without-carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 and Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. The Dreamcast's SH4 CPU lacks a multiply-without-carry instruction, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: ** top left quadrant is '''0''' ** top right quad is '''BOIN-width / 2''' ** bottom left is '''BOIN-width * (BOIN-height / 2)''' ** bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] c20d64f43a930e3648ce11da897e46a322ab8548 2971 2970 2023-05-14T06:19:58Z Unknown user 0 /* Look-up Table Hack */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. A problem with using Z-ordered curves is that it's expensive to compute every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation, covered below. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Look-up Table Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF];</syntaxhighlight> For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == Non-Dreamcast Bit-twiddling Hacks == On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. As the Dreamcast lacks these instructions, this is not a viable dreamcast solution. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied-without-carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 and Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. The Dreamcast's SH4 CPU lacks a multiply-without-carry instruction, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture Lets start with a small example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: ** top left quadrant is '''0''' ** top right quad is '''BOIN-width / 2''' ** bottom left is '''BOIN-width * (BOIN-height / 2)''' ** bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] b69ba80c38da6ff443e710a9ba7a8b49c71d41ad 2972 2971 2023-05-14T06:22:00Z Unknown user 0 /* Protofall's Implementation */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. A problem with using Z-ordered curves is that it's expensive to compute every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation, covered below. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. == Look-up Table Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF];</syntaxhighlight> For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == Non-Dreamcast Bit-twiddling Hacks == On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. As the Dreamcast lacks these instructions, this is not a viable dreamcast solution. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied-without-carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 and Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. The Dreamcast's SH4 CPU lacks a multiply-without-carry instruction, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: ** top left quadrant is '''0''' ** top right quad is '''BOIN-width / 2''' ** bottom left is '''BOIN-width * (BOIN-height / 2)''' ** bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] c0337c42e83131fc1162b9c3743bbb1e68799359 2973 2972 2023-05-14T06:22:19Z Unknown user 0 /* Conceptualizing Twiddling */ wikitext text/x-wiki == General Idea == Twiddling, sometimes referred to as Swizzling in Playstation communities, and better known as Morton Encoding or a [https://en.wikipedia.org/wiki/Z-order_curve#l134 Z/N-Ordered curve], is a method of data organization that retains [https://en.wikipedia.org/wiki/Locality_of_reference#L146 Locality of Reference], which means that elements that reside physically close together in space, will be grouped together in memory. In the context of texture organization, this means that twiddling an image will make adjacent pixels to the right and below any given pixel reside close together in memory. This yields numerous benefits, such as easier calculation for AA and a texel configuration necessary for [https://en.wikipedia.org/wiki/Vector_quantization#L135 Vector Quantization] compression. == Origins and Classical Implementation == The term "Twiddling" comes from the hacker term "bit-twiddling" owing to the classical way to calculate a Z-Ordered curve by manipulating the bits that make up the data (texel) index. The bit-twiddling way to arrive at a morton code is to take the binary representation of the X and Y coordinates of a texel and interleave them into one bitstring. The resultant bitstring will be twice the size of each individual input bitstring. For example, say you have a 4-bit number representing the X position of a Texel in a texture (e.g. XXXX) and you had a 4-bit number representing the Y position of a Texel (eg. YYYY), then your Z-Order position would be XYXY-XYXY (8-bit). This number is the index of where this texel lies in a new array that constitutes all the twiddled texels in the texture. If you convert every texel in the source texture into this new twiddled texture array, then iterating through the index will be the equivalent of navigating the source texture in a Z-pattern. Whether one is a Z-ordered curve or an N-ordered curve depends on whether you shift the X or Y bitstring, effectively making the traversal width by height (Z) or height by width (N). Technically, the dreamcast uses an N-ordered curve. A problem with using Z-ordered curves is that it's expensive to compute every frame because it uses division and multiplication heavily. Thus there exists numerous bit-twiddling hacks to speed up this operation, covered below. == Conceptualizing Twiddling == Lets start with a recap of what Twiddled textures even are. Twiddled textures is just a particular way of re-organising pixels in an image so they're quicker to render. [[File:Twiddle.png|thumb]] The example image where the numbers represent the original un-twiddled indexes and the "inverted Ns" show the original flow of indexes. Indexes from the original image were calculated from left to right, top to bottom (Scanline order). So we can see after index 0, number 1 is just below, 2 is to the right of 0 and 3 is just below 2. Then if we go to the next biggest inverted N we can see the order '''{0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}''' following the same inverted N pattern. So if we are given index '''i''' from an untwiddled image and wished to find the twiddled index, then its a process of recursively narrowing down what part of the twiddled image that pixel now lives in. Example: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + == Look-up Table Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned short MortonTable256[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; unsigned short x; // Interleave bits of x and y, so that all of the unsigned short y; // bits of x are in the even positions and y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. z = MortonTable256[y >> 8] << 17 | MortonTable256[x >> 8] << 16 | MortonTable256[y & 0xFF] << 1 | MortonTable256[x & 0xFF];</syntaxhighlight> For more speed, use an additional table with values that are MortonTable256 pre-shifted one bit to the left. This second table could then be used for the y lookups, thus reducing the operations by two, but almost doubling the memory required. Extending this same idea, four tables could be used, with two of them pre-shifted by 16 to the left of the previous two, so that we would only need 11 operations total. == Binary Magic Numbers Hack == Taken from [https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup#Stanford Stanford Bit-twiddling hacks page]. <syntaxhighlight lang="c">static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; static const unsigned int S[] = {1, 2, 4, 8}; unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x unsigned int y; // are in the even positions and bits from y in the odd; unsigned int z; // z gets the resulting 32-bit Morton Number. x and y must initially be less than 65536. x = (x | (x << S[3])) & B[3]; x = (x | (x << S[2])) & B[2]; x = (x | (x << S[1])) & B[1]; x = (x | (x << S[0])) & B[0]; y = (y | (y << S[3])) & B[3]; y = (y | (y << S[2])) & B[2]; y = (y | (y << S[1])) & B[1]; y = (y | (y << S[0])) & B[0]; z = x | (y << 1);</syntaxhighlight> == Non-Dreamcast Bit-twiddling Hacks == On modern x86_64 processors from Intel actually have instructions built in to handle z-ordered curves. These are the Parallel Bit Deposit (PDEP) and Parallel bit Extraction (PEXT) instructions, which can be used in conjunction to interleave a bitstring. As the Dreamcast lacks these instructions, this is not a viable dreamcast solution. Another method for twiddling comes from multiplication without carry. A number multiplied upon itself using a carry-less multiplication will yield the original bitstring of the number interleaved with 0s. For example, given that the number 255 is 1111-1111 in binary, 255 multiplied-without-carry by 255 reveals a 16-bit number that is (1010-1010 1010-1010). Thus, if you use multiply without carry on the X and Y position of the texel in the texture, you'll arrive at two 16-bit numbers, e.g. X0X0-X0X0 X0X0-X0X0 and Y0Y0-Y0Y0 Y0Y0-Y0Y0. If you bitshift the X value to the right by 1, and then OR the X bitstring by the Y bitstring, the resultant 16-bit bitstring will be twiddled. The Dreamcast's SH4 CPU lacks a multiply-without-carry instruction, although you could create one that uses only addition like so: <syntaxhighlight lang="c">int multiplyWithoutCarry(int a, int b) { int result = 0; int multiplier = 1; while (b != 0) { int digit = b; int temp = a; while (digit > 9) { digit -= 10; temp += a; } while (digit > 0) { result += temp; digit--; } int divisor = 10; int tempMultiplier = multiplier; while (divisor > 1) { if (divisor <= tempMultiplier) { tempMultiplier -= divisor; divisor = divisor << 1; multiplier = multiplier << 1; } else { divisor = divisor >> 1; tempMultiplier = tempMultiplier >> 1; } } b -= tempMultiplier; } return result; }</syntaxhighlight> == Protofall's Implementation == How to generated the twiddled index from an untwiddled texture: Original: Twiddled: 0 1 2 3 0 2 8 A 4 5 6 7 1 3 9 B 8 9 A B 4 6 C E C D E F 5 7 D F G H I J G I O Q K L M N H J P R O P Q R K M S U S T U V L N T V W X Y Z W Y % & ~ ! # $ X Z ^ * % ^ & * ~ # ( _ ( ) _ + ! $ ) + The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid '''2^x * 2^'''y sizes, where x and y are whole numbers. Now lets say we want to find the twiddled index of the untwiddled '''"O"''' pixel (index 24). By hand we can work it out and tell the twiddle index should be "18", but what algorithm/logic can we use to find this automatically for any '''i'''? Here are my steps: * We first need to start by figuring out the "Biggest-Order Inverted-N" ('''BOIN''') that fits in this image. * Now if our starting image was a square, then the BOIN is the same size as the image * For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width * If we start off with a rectangle, then we need to do an extra step that squares can skip. * Notice how we can completely encapsulate the whole image with '''(bigger_side / smaller_side) == 3''' BOINs? Our first step is to determine which of these BOINs our index '''i''' belongs in. * We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3. * Therefore using the formula '''k = floor(i / (BOIN area == 4 * 4 = 16)) == 1''' we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since '''k''' is of the set '''{0,1,2}''') * Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is "16". Keep track of this value, lets call it '''d''' * Also keep track of the index where our BOIN starts according to the twiddled texture, this is also '''16''' in this case. Lets add this to a running sum '''s''' * Forget about the other two BOINs and subtract '''d''' from the indexes in our new BOIN as well as '''i''' So now we have: i == 8 0 2 8 A 1 3 9 B 4 6 C E 5 7 D F Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs? * In order to solve a square BOIN, we need to determine what quadrant our pixel is in * So we determine how many pixels are in each quadrant (4 per quadrant here, '''== a'''), Then calculate '''k = floor(i / a) == 2''' to know its in the 3rd quadrant ('''k''' is in the set '''{0,1,2,3}'''). * That means its in the top right. So we need to set '''d = a * k'''), add our new '''s''' value to the running sum, discard the other quadrants, then subtract '''i''' and the new BOIN's indexes by '''d''' * The easy way to calculate the new part of '''s''' is that: ** top left quadrant is '''0''' ** top right quad is '''BOIN-width / 2''' ** bottom left is '''BOIN-width * (BOIN-height / 2)''' ** bottom right is '''(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)''' Now we have: i == 0 0 2 1 3 You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum '''s''' (16 + 2 + 0 == 18) == DISCLAIMER == This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2. For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP] aebf29c7fe47f5ec6807b77ac39adcc77da42440 Development 0 2 2969 2198 2023-05-14T06:01:33Z Unknown user 0 wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] 4b29b853b891e2b4f68a224ab033517d2099ac60 SH4 in Compiler Explorer 0 733 2974 1907 2023-05-17T03:43:35Z Unknown user 0 Added templates for GCC13 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. 9c77f3e8161e64f9b100660e0729c2d56a2b4e6e 2975 2974 2023-05-17T11:57:39Z Unknown user 0 Added more information about compiler optimizations and a link to the compiler benchmarks wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. b0cc307c67acc7102baffcdbe9a6f3dd2bfcdef0 2976 2975 2023-05-17T12:01:37Z Unknown user 0 Added templates for 9.5.0 and 4.9.4 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 6cf052c01236c90e75e692db975d51fc18742505 2978 2976 2023-05-17T12:06:51Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example.]] * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 2e89d6bf0b9b909d33038ab2e1fd3ac346b73e43 2979 2978 2023-05-17T12:08:00Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example.]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 4a0431bc2a935034fb1693fbdab2b20c5cfcefd0 2980 2979 2023-05-17T14:36:05Z Unknown user 0 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * -ml: Compile code for the processor in little-endian mode * -m4-single-only: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * -ffast-math: Breaks strict IEEE compliance and allows for faster floating point approximations * -O3: optimization level 3 * -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. * -mfsca: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 5af10fe1c9ea6fdc7912631d2521c2c91626c390 2981 2980 2023-05-17T14:41:11Z Unknown user 0 /* Configuration */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: Compile code for the processor in little-endian mode * <code>-m4-single-only</code>: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: Breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations. * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. * The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. * It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 737cbee847feffa0a2211d19a55a3ec56fd9f2ae 2982 2981 2023-05-17T14:45:10Z Unknown user 0 /* Tips and Notes */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: Compile code for the processor in little-endian mode * <code>-m4-single-only</code>: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: Breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations. * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 4af100d4e205e54e5b4f10992d5d07885a979180 File:GCC Compiler Benchmarks.png 6 1376 2977 2023-05-17T12:04:57Z Unknown user 0 wikitext text/x-wiki Benchmarks of runtime performance and binary file size of KOS's pvrmark example between the various toolchain versions with various flags ead0da0e70ee73e322a42fb6b70ded1afc025bd9 Getting Started with Dreamcast development 0 694 2983 2947 2023-05-19T19:28:26Z Unknown user 0 /* Compiling and running an example program */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= TODO: Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. b1ed69b55555a72c970adbefe3f2b5803d090f75 2984 2983 2023-05-19T19:29:29Z Unknown user 0 /* Burning your project to CD and distributing */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes compilers for both the Dreamcast's main SH4 CPU as well as the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= TODO: Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= TODO: Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. b05ac7b24740b308f5927a397c458cef4156f832 2985 2984 2023-05-19T21:13:55Z Unknown user 0 /* Introduction */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Compile the toolchain: make This can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. If desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= TODO: Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= TODO: Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 70caf49fbb39f9e4f4f2f239f7699272b0ae43bb 2986 2985 2023-05-19T21:21:31Z Unknown user 0 /* Compiling the toolchain */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Now we will compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This process can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Compiling and running an example program= TODO: Give a tutorial on writing and compiling very basic helloworld-style C program, configuring serial or IP link, and running the example. Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= TODO: Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. cb220cbc7f2b2f4be8a3fdbc8065c83ac496963c 2987 2986 2023-05-19T21:52:25Z Unknown user 0 /* Compiling and running an example program */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Now we will compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This process can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning your project to CD and distributing= TODO: Explain how to compile a CD project using mkdcdisc or similar tools, and how to package it for distribution. [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Further reading= Links to articles for using gdb, integrating the dev setup with an IDE, etc. 586e278ef5e700b6e19768b89dec2f22753d3b47 2988 2987 2023-05-19T22:01:15Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Steps required for Windows 10/WSL, writing and compiling an example program, setting up a debug link, and building and burning a CD for distribution =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Now we will compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This process can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. ad5a99246907f302e4fe111872eaad78fc59911b 2989 2988 2023-05-19T22:01:38Z Unknown user 0 /* This article is actively being worked on */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Now we will compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This process can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. 498bc1be72d602531d5cb5a35062817c605e5209 2990 2989 2023-05-19T22:03:24Z Unknown user 0 wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Now we will compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This process can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. 918645ee79621fec633b833883c0b1f6d770b9e5 2992 2990 2023-05-19T23:43:56Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Preparing the toolchain=== Run the download and unpack scripts: ./download.sh ./unpack.sh ===Compiling the toolchain=== Now we will compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This process can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. f2c972bfa110dc6c988f4b2969a2aff5afb95cce VMU development 0 99 2993 2923 2023-05-23T01:50:02Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 0dbdcd81af032687d0f99d7dca7ebcb9e4983ae9 2995 2993 2023-05-23T01:53:02Z GyroVorbis 13 /* AA Batter-Powered VMU Mod */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - A smaller hangout for DC developers with many VMU-focused developers, including the authors of WaterBear, ElysianVMU, and uM23 === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 1f9515644d9cf7e9d4c4c18efd9587ab8388c0d9 2998 2995 2023-05-23T02:00:44Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 680c2dbb56f46328a14c6ca0c65814f1f7ec75ff 2999 2998 2023-05-23T02:01:08Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual f611d5724f14fcea4987160c2c04020ba3e7ef54 File:Aa vmu mod.png 6 1377 2994 2023-05-23T01:52:44Z GyroVorbis 13 wikitext text/x-wiki AA VMU Battery Mod by Jeff Chen c18b15bcd6dc4d362e1aee2ccb24ea7afba28978 VMU hardware overview 0 147 2996 1549 2023-05-23T01:54:58Z GyroVorbis 13 wikitext text/x-wiki [[File:VMU Device.jpg|thumb|Visual Memory Unit]] * '''CPU''': 8-bit Sanyo LC86K87 * '''Clock''': 32.8KHz quartz oscillator, 879.2kHz RC oscillator, 6MHz CF oscillator * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes of additional WRAM * '''ROM''': 4KB OS/firmware functionality, 16KB system BIOS program area * '''Flash''': 128 KB (200 blocks) with 8-bit FAT filesystem * '''Power source''': Two CR2032 batteries with auto-off function and low-battery detection circuit * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel PWM sound source * '''Input''': 4-button D-pad, 2 general-purpose buttons (A, B), MODE, SLEEP * '''Timer''': Base Timer (14-bit binary up counter), 2xTimer Circuits (16-bit timer/counter with pulse generator) * '''Serial Interface''': Dedicated Maple interface (VMU-to-Dreamcast) or Synchronous 8-bit serial interface with 2 transfer channels (VMU-to-VMU) [[:File:Vmu_Manual.pdf|Instruction Manual]] 04f6ddf3cb90fdee87740c16525e70df206ca308 2997 2996 2023-05-23T01:55:40Z GyroVorbis 13 wikitext text/x-wiki [[File:VMU Device.jpg|thumb|Visual Memory Unit]] * '''CPU''': 8-bit Sanyo LC86K87 * '''Clock''': 32.8KHz quartz oscillator, 879.2kHz RC oscillator, 6MHz CF oscillator * '''RAM''': 256 bytes for applications, 256 reserved for system BIOS, 512 bytes of additional WRAM * '''ROM''': 4KB OS/firmware functionality, 16KB system BIOS program area * '''Flash''': 128 KB (200 blocks) with 8-bit FAT filesystem * '''Power source''': Two CR2032 batteries with auto-off function and low-battery detection circuit * '''Display''': 48 dot Width x 32 dot Height resolution, Monochrome * '''Display size''': 37 mm (1.46 inches) Width x 26 mm (1.02 inches) Height * '''Sound''': PWM sound chip, 1-channel 8-bit PWM sound source * '''Input''': 4-button D-pad, 2 general-purpose buttons (A, B), MODE, SLEEP * '''Timer''': Base Timer (14-bit binary up counter), 2xTimer Circuits (16-bit timer/counter with pulse generator) * '''Serial Interface''': Dedicated Maple interface (VMU-to-Dreamcast) or Synchronous 8-bit serial interface with 2 transfer channels (VMU-to-VMU) [[:File:Vmu_Manual.pdf|Instruction Manual]] 7f7683a7a02576a9d6bd2414ade29e644327cabe VMU mods 0 713 3000 1593 2023-05-23T20:36:44Z GyroVorbis 13 wikitext text/x-wiki There exist various hardware modifications for the VMU/VMS for things ranging from rechargable batteries and USB power to LCD screens and CPU overclocking. {{DCWiki:Stub}} # LED Backlight # USB Power Cable # AA Battery Pack # Overclocking 75236bbd219de143f962bfd6b9f25da36551b1f7 DCEmulation gems 0 1378 3001 2023-05-24T16:51:19Z GyroVorbis 13 Created page with "[CDDA Looping https://dcemulation.org/phpBB/viewtopic.php?t=106083] [High Performance Rendering https://dcemulation.org/phpBB/viewtopic.php?t=106078] [Compiler Benchmarks https://dcemulation.org/phpBB/viewtopic.php?t=106068]" wikitext text/x-wiki [CDDA Looping https://dcemulation.org/phpBB/viewtopic.php?t=106083] [High Performance Rendering https://dcemulation.org/phpBB/viewtopic.php?t=106078] [Compiler Benchmarks https://dcemulation.org/phpBB/viewtopic.php?t=106068] a40f73b1c77f6af2dfb3a724ac4827634aebcb3a 3002 3001 2023-05-24T16:52:34Z GyroVorbis 13 wikitext text/x-wiki [https://dcemulation.org/phpBB/viewtopic.php?t=106083 CDDA Looping] [https://dcemulation.org/phpBB/viewtopic.php?t=106078 High Performance Rendering] [https://dcemulation.org/phpBB/viewtopic.php?t=106068 Compiler Benchmarks] ef2fd3b25d72cb2717c57778ab8f828e125e4b6d 3003 3002 2023-05-24T16:53:29Z GyroVorbis 13 wikitext text/x-wiki This page is meant to serve as a quick reference to some of the most precious Dreamcast development resources and gems posted on the DCEmulation.org forums. * [https://dcemulation.org/phpBB/viewtopic.php?t=106083 CDDA Looping] * [https://dcemulation.org/phpBB/viewtopic.php?t=106078 High Performance Rendering] * [https://dcemulation.org/phpBB/viewtopic.php?t=106068 Compiler Benchmarks] f58b768267d89c12a9c25c2f51e971793a7d2a06 3004 3003 2023-05-24T16:57:18Z GyroVorbis 13 wikitext text/x-wiki This page is meant to serve as a quick reference to some of the most precious Dreamcast development resources and gems posted on the DCEmulation.org forums. * [https://dcemulation.org/phpBB/viewtopic.php?t=106083 CDDA Looping] * [https://dcemulation.org/phpBB/viewtopic.php?t=106078 High Performance Rendering] * [https://dcemulation.org/phpBB/viewtopic.php?t=106068 Compiler Benchmarks] * [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=104921&p=1055904#p1055904 OARGB Shading] * [https://dcemulation.org/phpBB/viewtopic.php?t=105407&hilit=performance+counters KOS vs Ninja Polygon Performance] ab886dc3ab4aa3949ab9d87ccdd44e2f5040474a 3005 3004 2023-05-24T17:00:53Z GyroVorbis 13 wikitext text/x-wiki This page is meant to serve as a quick reference to some of the most precious Dreamcast development resources and gems posted on the DCEmulation.org forums. * [https://dcemulation.org/phpBB/viewtopic.php?t=106083 CDDA Looping] * [https://dcemulation.org/phpBB/viewtopic.php?t=106078 High Performance Rendering] * [https://dcemulation.org/phpBB/viewtopic.php?t=106068 Compiler Benchmarks] * [https://dcemulation.org/phpBB/viewtopic.php?f=29&t=104921&p=1055904#p1055904 OARGB Shading] * [https://dcemulation.org/phpBB/viewtopic.php?t=105407&hilit=performance+counters KOS vs Ninja Polygon Performance] * [https://dcemulation.org/phpBB/viewtopic.php?p=1015003&hilit=puru+puru#p1015003 Maple Tests] * [https://dcemulation.org/phpBB/viewtopic.php?t=48462&hilit=puru+puru&start=60 Puru Puru/Rumble] 4a0e642eec2428ffa7beade02db372125549e015 Qt Creator Dreamcast Development Environment 0 1379 3006 2023-05-25T23:01:26Z GyroVorbis 13 Created page with "This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this t..." wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. To start with, this tutorial makes the following assumptions: # You have already installed and set up your KallistiOS development environment. # You have already downloaded and installed Qt Creator 3abb9000c12a551e5182ab3f457572e772c35f6e 3007 3006 2023-05-25T23:12:11Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Creator] (version 10.0.1 was used for this tutorial). d14ef0420b736c7c3c3bac0133a779ac8d464d3e 3008 3007 2023-05-25T23:12:23Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). 613463a0b53aa8df5d1d348baf6830f3efeded35 3009 3008 2023-05-25T23:15:35Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain 52116edee3a274de05adaecc489d3d78d3881a63 3010 3009 2023-05-25T23:22:04Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * `cp config.mk.legacy.sample config.mk` for GCC4.7.4. * `cp config.mk.stable.sample config.mk` for GCC9.3.0. * `cp config.mk.testing.sample config.mk` for GCC13.1.0. a0d1049642afd43f3df449beb50bc3b22eb6f21e 3011 3010 2023-05-25T23:22:39Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: cp config.mk.legacy.sample config.mk # for GCC4.7.4. cp config.mk.stable.sample config.mk # for GCC9.3.0. cp config.mk.testing.sample config.mk # for GCC13.1.0. 8ca7a95b96c3c09f268b2735138b0e23606c7fc3 3012 3011 2023-05-25T23:23:25Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: GCC 4.7.4: cp config.mk.legacy.sample config.mk GCC 9.3.0: cp config.mk.stable.sample config.mk GCC 13.1.0: cp config.mk.testing.sample config.mk d822187317a97139dc5a8121ccae6fd737267cd1 3013 3012 2023-05-25T23:23:47Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: GCC 4.7.4: cp config.mk.legacy.sample config.mk GCC 9.3.0: cp config.mk.stable.sample config.mk GCC 13.1.0: cp config.mk.testing.sample config.mk aae651496dd649579f560910162323a01154e309 3014 3013 2023-05-25T23:23:58Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: GCC 4.7.4: cp config.mk.legacy.sample config.mk GCC 9.3.0: cp config.mk.stable.sample config.mk GCC 13.1.0: cp config.mk.testing.sample config.mk b0ae2d721b2a20ea7b8cac361529ec5c9baadb1f 3015 3014 2023-05-25T23:24:25Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk 3ba2cff7d0fed072ff6060cfe4f0e36b132aeb6c 3016 3015 2023-05-25T23:46:28Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. After awhile, it should be built. You can verify this by checking to see whether you have `/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb` or, if you're currently within a DC environment, simply checking to see if you can run `sh-elf-gdb`. If everything goes well, it should start up and leave you at a command prompt. {{Note|GDB Python Support|Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' }} 7ebe6c86f72585d8c42ff6c2ee04166a5b6e8a17 3017 3016 2023-05-25T23:47:20Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. After awhile, it should be built. You can verify this by checking to see whether you have `/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb` or, if you're currently within a DC environment, simply checking to see if you can run `sh-elf-gdb`. If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' 116b1c736ad42098da7764174d25943c54e917c3 3018 3017 2023-05-25T23:49:43Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. After awhile, it should be built. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' c8308ae2ae7d5a737d665699a3bcf6ef5d66a014 3019 3018 2023-05-25T23:51:41Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). === Installing GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' a9a7602dc7410287ae944ee4e8ac0170afeb314c 3020 3019 2023-05-25T23:53:56Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Setting up Qt Creator == 2db90f25cbad910203e0771a6b2724f03a1c5004 3021 3020 2023-05-26T00:06:13Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Setting up Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. == Setting up the Kit == First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * ```ABIs```: sh-baremetal-generic-elf-32bit * ```Version```: The correct version number corresponding to the toolchain you chose 0ace974011edbc40c098984a869c42a4a1764500 3022 3021 2023-05-26T00:06:36Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Setting up Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. == Setting up the Kit == First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose 4279ef97ce46ef99456fa15f35170f283b4f8c2c 3023 3022 2023-05-26T00:08:11Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Configuring the Kit === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ada1530fa78d6915a236ae452f92cce78b6d7567 3024 3023 2023-05-26T00:15:01Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Configuring the Kit === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. f58787132643b4593094ce12f5fd77469d87b223 3025 3024 2023-05-26T00:15:57Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Configuring the Kit === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ==== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. 3378e2854b340293c2dcebea4895a95ff0bab9ec 3026 3025 2023-05-26T00:16:23Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building GDB === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying GDB === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying GDB Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Configuring the Kit === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. e2f7ac7e5c2f8f46db228a493e495d8b6fd77ee7 3027 3026 2023-05-26T00:17:19Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Configuring the Kit === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. 13e18c369af037036787fea845ad5d5bd6804eeb 3028 3027 2023-05-26T00:18:01Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Kit === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. 5557c771b2e968f2b5b47f28cf3f2a47ff21293e 3029 3028 2023-05-26T00:23:41Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC <VERSION> * '''Compiler''': * '''C''': Dreamcast GCC * '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB 37f67825f887811be52bef917e9c268bfe2e480d 3030 3029 2023-05-26T00:24:32Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC <VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB bea7214591a61ba6fd15daadfc4c6c87f48abd42 3032 3030 2023-05-26T00:34:00Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|thumb|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. 6b47ca27d1c95d472d6793c694a3998370a8383f 3033 3032 2023-05-26T00:36:23Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|thumb|left|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations. You can now build CMake projects for the Sega Dreamcast. ce4780ba01a64b14784285c3ad38200e890dfa24 3034 3033 2023-05-26T00:39:26Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations. You can now build CMake projects for the Sega Dreamcast. 2b617d9103c28d0c38d063e46d1c2d8fc128e9d6 3035 3034 2023-05-26T01:15:35Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs which can arguably have even better integration. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! cadca12689c1823ccfde873ea1366d965429e24b 3036 3035 2023-05-26T01:20:16Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! abd08e179ff90817de74f51dfa02a41aaf1ea88a 3037 3036 2023-05-26T01:21:49Z GyroVorbis 13 GyroVorbis moved page [[QtCreator Debugging]] to [[Qt Creator Dreamcast Development Environment]]: Previous title sold the article short wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! abd08e179ff90817de74f51dfa02a41aaf1ea88a 3039 3037 2023-05-26T01:25:00Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([GyroVorbis Falco Girgs]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! 213b699b7f61e652e9005de1154874b9644ae901 3040 3039 2023-05-26T01:26:11Z GyroVorbis 13 wikitext text/x-wiki This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! 8e5ac5eb67cf1e2c3fda3cc282b0db1ff97f602e File:Dreamcast icon.png 6 1380 3031 2023-05-26T00:32:33Z GyroVorbis 13 wikitext text/x-wiki Icon used for our Dreamcast Qt Creator Kit c7a81d7d56456881df7f42057d6c8b1556b372d6 QtCreator Debugging 0 1381 3038 2023-05-26T01:21:49Z GyroVorbis 13 GyroVorbis moved page [[QtCreator Debugging]] to [[Qt Creator Dreamcast Development Environment]]: Previous title sold the article short wikitext text/x-wiki #REDIRECT [[Qt Creator Dreamcast Development Environment]] 702175ef106fbdd110eecd5103812c7d0b0f6cad User:GyroVorbis 2 116 3041 332 2023-05-26T01:28:11Z GyroVorbis 13 wikitext text/x-wiki Infamous lead developer of Elysian Shadows, ESTk, and ElysianVMU, widely hated for being late on Kickstarter, but THE PROJECT IS HIS LIFE, AND HE'S WORKING ON IT and fully intends to make it up to all of you. :) I've recently begun to atone for my sins by giving back to the Dreamcast community as a KOS developer and writing content here for this wiki. GitHub: https://github.com/gyrovorbis Twitter: https://twitter.com/falco_girgis Discord: https://discord.gg/SX2txgr LinkedIn: https://www.linkedin.com/feed/ 1b89d729ccf29d311910f948dd3d2458f20dcc1c 3042 3041 2023-05-26T01:29:19Z GyroVorbis 13 wikitext text/x-wiki My name is Falco Girgis. I am the infamous lead developer of Elysian Shadows, ESTk, and ElysianVMU. I am widely hated for being late on Kickstarter, but THE PROJECT IS MY LIFE, AND I'M WORKING ON IT and fully intend to make it up to all of you. :) I've recently begun to atone for my sins by giving back to the Dreamcast community as a KOS developer and writing content here for this wiki. * GitHub: https://github.com/gyrovorbis * Twitter: https://twitter.com/falco_girgis * Discord: https://discord.gg/SX2txgr * LinkedIn: https://www.linkedin.com/feed/ 3af732ccd6208e8522f16c6383153fd81a92ccf2 3043 3042 2023-05-26T01:30:53Z GyroVorbis 13 wikitext text/x-wiki My name is Falco Girgis. I am the infamous lead developer of Elysian Shadows, ESTk, and ElysianVMU. I am widely hated for being late on Kickstarter, but THE PROJECT IS MY LIFE, AND I'M WORKING ON IT and fully intend to make it up to all of you. :) I've recently begun to atone for my sins by giving back to the Dreamcast community as a KOS developer and writing content here for this wiki. Feel free to come hang out with me on Discord or follow me on Twitter or something. I'm happy to help! * GitHub: https://github.com/gyrovorbis * Discord: https://discord.gg/SX2txgr * Twitter: https://twitter.com/falco_girgis * LinkedIn: https://www.linkedin.com/feed/ 52e488551400013fff1cde431c7996abeaa6f378 VMU development 0 99 3044 2999 2023-05-26T15:04:01Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock. ==== 2-Tone Buzzer Generation ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual d0b07497eb61cd5f3453366c3f71fa43ad1de792 3045 3044 2023-05-26T15:04:36Z GyroVorbis 13 /* 2-Tone Buzzer Generation */ wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 90bab5b2ee6a1b5d31cb04e8795cb37c79bc3aae 3046 3045 2023-05-26T15:05:47Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual dce3ac047b476a4e1f2bb144c5fcc90522978a86 3047 3046 2023-05-26T15:06:15Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual d4c5dac48130b1df500e469193c7f091a6887bc8 3048 3047 2023-05-26T15:10:12Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 994777e398a5c98d48940c12aabb1bbdf7540322 3049 3048 2023-05-26T15:19:51Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available and will be updated every time a new resource is found or new discovery is made. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual f677e0709eb44e4076ab307a297b62e44e11ee25 VMU development 0 99 3050 3049 2023-05-26T15:23:07Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's VMU (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available and will be updated every time a new resource is found or new discovery is made. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU serial connectivity]] Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual c4474042840e0193f0ba6bc3dc19558226d96bb7 3051 3050 2023-05-26T15:43:31Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's Visual Memory Unit or "VMU" (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available and will be updated every time a new resource is found or new discovery is made. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site]. A combination of this site and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU serial connectivity]] Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 4ff651b3b5adca8361dc7dab35e265e2134bf706 Development 0 2 3052 2969 2023-05-26T20:12:09Z GyroVorbis 13 wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] === Debugging & profiling === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] * [[CLion Debugging]] * [[Visual Studio Code Debugging]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] fd995f8a7bc509fa308cb4b19471e18b99afd84c 3053 3052 2023-05-26T20:13:13Z GyroVorbis 13 wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Linux mint (or Ubuntu)]] * [[Building KOS under Windows Subsystem for Linux (Windows 10 only)]] * [[Building KOS on macOS]] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code Debugging]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] dbcac9b3c21812c732a4b5c3d159fd16c9d3cac1 3062 3053 2023-06-04T22:01:23Z Darc 1 /* KallistiOS */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[Building the required toolchains for Sega Dreamcast development]]==== ====[[KallistiOS]]==== * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code Debugging]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] a464ff62ca4151f0e9ffe0f82f1036f1bbc5c5ec 3064 3062 2023-06-04T22:06:16Z Darc 1 wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code Debugging]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] 1e7f03aacd3d55ef911df3a8effdab09b2a36b22 3072 3064 2023-06-06T18:58:42Z Tchan 166 /* Environments and IDEs */ removed "Debugging", the page contains more than pure debugging wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] c500d07ae944b38afae0f14cc5a8ea19a57e8dc6 Qt Creator Dreamcast Development Environment 0 1379 3054 3040 2023-05-27T08:11:32Z GyroVorbis 13 wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! d759c6e395775b138b3ee4ca33645bae6917b473 3094 3054 2023-06-08T03:24:56Z GyroVorbis 13 wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment and the GDB debugger. When using QtCreator, you will be using CMake as your build system and a CMakeLists.txt file as your project file. Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. === Prerequisites === To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! 2aa4c9e4f9d16fa601a314db2320ad6b3d065fa3 3095 3094 2023-06-08T03:28:48Z GyroVorbis 13 wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment, the CMake build system, and the GDB debugger. == Motivation == Choosing Qt Creator as your IDE has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. == Prerequisites == To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! 5d09e7637bcbc3ad34089b3674a19285c578eb32 3096 3095 2023-06-08T03:29:26Z GyroVorbis 13 wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment, the CMake build system, and the GDB debugger. == Motivation == Choosing Qt Creator as your IDE for Dreamcast development has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a multitude of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. == Prerequisites == To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! b057d8ae03a22f7b02ac402c742573e8f0b2592c 3097 3096 2023-06-08T03:31:49Z GyroVorbis 13 wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment, the CMake build system, and the GDB debugger. == Motivation == Choosing Qt Creator as your IDE for Dreamcast development has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a variety of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. * [https://dreamcast.wiki/Visual_Studio_Code Visual Studio Code * [https://dreamcast.wiki/CLion_Debugging CLion] == Prerequisites == To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! 39526794c2467377c0a40017b2d6d9ddc106bbd0 3098 3097 2023-06-08T03:31:58Z GyroVorbis 13 wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment, the CMake build system, and the GDB debugger. == Motivation == Choosing Qt Creator as your IDE for Dreamcast development has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a variety of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way. * [https://dreamcast.wiki/Visual_Studio_Code Visual Studio Code] * [https://dreamcast.wiki/CLion_Debugging CLion] == Prerequisites == To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! 9f7132086c21f7976e24c7515ecd3803883dc905 3099 3098 2023-06-08T03:32:16Z GyroVorbis 13 /* Motivation */ wikitext text/x-wiki '''NOTE: This page is a work in progress! It will get you set up for compiling and 90% ready for debugging, but the final bit and screenshots are incoming still.''' This is a guide to set up the Qt Creator IDE for compilation and source-level debugging on the Sega Dreamcast using the KallistiOS development environment, the CMake build system, and the GDB debugger. == Motivation == Choosing Qt Creator as your IDE for Dreamcast development has several strengths, such as being massively cross-platform, supporting a multitude of devices and toolchains (Windows, Mac, Linux, iOS, Android, WebAssembly, etc), and being extremely easy to add additional toolchains to. I ([[User:GyroVorbis|Falco Girgs]]) build all of my projects with standard CMake using the CMake toolchain file provided within KOS, and I can swap between targeting a variety of platforms by simply changing an option in a drop-down menu. Not only that, but any active breakpoints or watch variables that I've set up on PC will seamlessly transition over to my Dreamcast and vice versa when changing between targets! However, the downside is that as of the writing of this tutorial (Qt Creator version 10.0.1), there are a few places where we are forced to do things that are slightly less than ideal or a bit hacky to maneuver around limitations in the configurability of the IDE. In my personal opinion, these are not actually a big deal, and your resulting environment is almost as easy to use as debugging locally; however, there are tutorials for other IDEs if having to click two buttons instead of one to start a remote debugging session or any of the little nuances here rub you the wrong way: * [https://dreamcast.wiki/Visual_Studio_Code Visual Studio Code] * [https://dreamcast.wiki/CLion_Debugging CLion] == Prerequisites == To start with, this tutorial makes the following assumptions: # You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. # You have already downloaded and installed [https://www.qt.io/product/development-tools Qt Creator] (version 10.0.1 was used for this tutorial). == Setting up GDB == Before we can begin configuring Qt Creator, we must install GDB, which is not installed by default with the KOS toolchain build scripts. === Building === The first thing we need to do is additionally set up and install the GDB debugger for the Dreamcast's GCC SH toolchain. Open a bash shell or whatever terminal you use to compile KOS code with and navigate back to the `dc-chain` folder within KOS, which was previously used to install the toolchains: cd /opt/toolchains/dc/kos/utils/dc-chain Once there, check to see whether you have a `config.mk` file which was used to build your toolchain previously. If you do, you can proceed to the next step. If you don't, you need to copy one of the three sample configuration files as your new `config.mk` file, depending on which version of the toolchain you had set up previously. If you aren't sure, you can run `sh-gcc-elf --version` and check which version of the compiler you had chosen. Next run one of the following commands: * GCC 4.7.4: cp config.mk.legacy.sample config.mk * GCC 9.3.0: cp config.mk.stable.sample config.mk * GCC 13.1.0: cp config.mk.testing.sample config.mk Finally, we're ready to actually download and install it. You can do so by running the following command: make gdb You should see a bunch of scrolling text as the make scripts download, extract, and begin building GDB. === Verifying Installation === After awhile, GDB should be built and installed into your DC toolchain. You can verify this by checking to see whether you have the executable. It is located at: /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb Alternatively, if you're currently within a DC environment, simply checking to see if you can run: sh-elf-gdb If everything goes well, it should start up and leave you at a command prompt. === Verifying Python Support === Note that Qt Creator requires that GDB be built with support for Python scripting extensions. This should be automatically detected and handled by the Makefiles which are checking to see whether Python is installed or not based on your path. You can verify that it was properly built with Python support by running the following command: gdb --batch -ex 'python import sys; print(sys.version)' == Configuring Qt Creator == Now that we have GDB downloaded and installed, it's time to tell Qt Creator how to use our shiny new Dreamcast toolchain. === Adding the Toolchain === First, select the "Preferences" option from the "Edit" file menu. A dialog window should open. Select first entry, "Kits" from the top of the navigator pane on the left. ==== Configuring GDB ==== Next select the right-most "Debuggers" tab from the main view. Depending upon what you installed with Qt Creator, you may or may not see some automatically detected debuggers that it has preconfigured for you. Next click "Add" to add a new Debugger entry. Then fill out the following fields: * '''Name''': Dreamcast GDB * '''Path''': Browse to where your sh-elf-gdb binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb by default. If everything is correct, you should see the following entries populated automatically: * '''Type''': GDB * '''ABIs''': sh-baremetal-generic-elf-32bit * '''Version''': The correct version number corresponding to the toolchain you chose ==== Configuring Compilers ==== Next, select the "Compilers" tab on the main tab widget. Again, depending on your Qt installation, you may or may not have a bunch of automatically detected compilers in your list. ===== C Compiler ===== First, we add the C compiler from our toolchain. Click the "Add" button in the top-right and select "GCC" from the dropdown. This should create a new entry in the compiler list. Configure it with the following settings: * '''Name''': Dreamcast GCC * '''Path''': Browse to where your sh-elf-gcc binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-gcc by default. If everything is good, Qt Creator should auto populate the last two fields: * '''ABI''': sh-baremetal-generic-elf-32bit * '''Target Triple''': sh-elf ===== C++ Compiler ===== Next, we add the C++ compiler from our toolchain. Click the "Add" button again, select "GCC" again, and this time configure it as such: * '''Name''': Dreamcast G++ * '''Path''': Browse to where your sh-elf-g++ binary wound up being installed. This is /opt/toolchains/dc/sh-elf/bin/sh-elf-g++ by default. As with previously, if everything went well, you should see the "ABI" and "Target Triple" fields automatically populated with the same values as with the C compiler. ==== Configuring the Kit ==== Finally, select the "Kits" tab from the main tab view. Qt Creator has automatically set up a kit for every platform you've installed a toolchain for (which could be none or many). We now need to add a custom Kit for the Sega Dreamcast. Click the "Add" button in the top-right of the main view to add an entry to the list of its. Configure it with the following fields: * '''Name''': Dreamcast GCC-<VERSION> * '''Compiler''': ** '''C''': Dreamcast GCC ** '''C++''': Dreamcast G++ * '''Debugger''': Dreamcast GDB * '''Qt Version''': None * '''CMake Generator''': Unix Makefiles Click on the "change" button to the right of the '''Environment''' field, and add the following: KOS_BASE=/opt/toolchains/dc/kos KOS_CC_BASE=/opt/toolchains/dc/sh-elf KOS_PORTS=/opt/toolchains/dc/kos-ports KOS_SUBARCH=dreamcast Click on the "change" button to the right of the '''CMake Configuration''' field. Append the following to the bottom of the textbox: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/toolchains/dc/kos/utils/cmake/dreamcast.toolchain.cmake Finally, if you want your setup to be badass looking like mine, you can optionally click on the tiny box to the right of the '''Name''' field and specify an icon for your kit. Here is the Dreamcast logo I have used: [[File:Dreamcast icon.png|50px|Icon Used for our custom Dreamcast Qt Creator Kit]] Click Apply and then OK to exit the dialog box. Congratulations! You can now build CMake projects for the Sega Dreamcast! c95ca478ea5df803acfb5e526e4544d91828b33e SH4 in Compiler Explorer 0 733 3055 2982 2023-05-27T10:15:13Z GyroVorbis 13 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: Compile code for the processor in little-endian mode * <code>-m4-single-only</code>: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: Breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC4). = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 711c7f4499d9e7546017192eefc6b51b10867753 3056 3055 2023-05-27T10:16:04Z GyroVorbis 13 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: Compile code for the processor in little-endian mode * <code>-m4-single-only</code>: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: Breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 46fb38828a104c1553d679f8b222cf731b8ab18b Getting Started with Dreamcast development 0 694 3057 2992 2023-06-04T19:49:11Z Darc 1 /* Setting up and compiling the toolchain with the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: ./cleanup.sh =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. 2b68d5e558011957e254db230bd57bea6ba2aba8 3079 3057 2023-06-07T11:50:06Z BBHoodsta 2 /* Cleaning up temporary files */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. 0686b63eb4c348ec61dca474da9f4e7f59ad0858 Libronin 0 167 3058 2942 2023-06-04T19:49:49Z Darc 1 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++,objc,obj-c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to skip copying KOS Newlib headers into toolchain And finally, download and build the toolchain. make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 31aa68a56acb9a09fcffe8c99440237dff44a890 Building KOS on Linux mint (or Ubuntu) 0 1382 3059 2023-06-04T21:58:34Z Darc 1 Redirected page to [[Getting Started with Dreamcast development]] wikitext text/x-wiki #REDIRECT [[Getting Started with Dreamcast development]] a1e05fc090c8ed627c8d10f1c1a1361a1453504f Building KOS under Windows Subsystem for Linux (Windows 10 only) 0 1383 3060 2023-06-04T21:59:08Z Darc 1 Redirected page to [[Getting Started with Dreamcast development]] wikitext text/x-wiki #REDIRECT [[Getting Started with Dreamcast development]] a1e05fc090c8ed627c8d10f1c1a1361a1453504f Building KOS on macOS 0 1384 3061 2023-06-04T21:59:50Z Darc 1 Redirected page to [[Getting Started with Dreamcast development]] wikitext text/x-wiki #REDIRECT [[Getting Started with Dreamcast development]] a1e05fc090c8ed627c8d10f1c1a1361a1453504f Building the required toolchains for Sega Dreamcast development 0 261 3063 944 2023-06-04T22:04:06Z Darc 1 Redirected page to [[Getting Started with Dreamcast development]] wikitext text/x-wiki #REDIRECT [[Getting Started with Dreamcast development]] a1e05fc090c8ed627c8d10f1c1a1361a1453504f Visual Studio Code 0 768 3065 1835 2023-06-06T17:54:03Z Tchan 166 starting to improve the Visual Studio Code page wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. === Prerequisites === To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]. * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial). === VSCode Setup === * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft === Setup per Project === (TODO) == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> f04b3ab7dda813a9227bd21f4c33eb234531281d 3066 3065 2023-06-06T18:10:43Z Tchan 166 starting to add VSCode Projects configuration wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. === Prerequisites === To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) === VSCode Setup === * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft === Setup per Project - Compilation === (all the following steps happen in Visual Studio Code) * Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) * (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) * Create a new subfolder ".vscode" * insert the following files in the ".vscode" subfolder: TODO: c_cpp_properties.json, kos_compile.sh, settings.json === Setup per Project - Debugging on a real Dreamcast === TODO === Setup per Project - Debugging on an emulator === TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> dc27b4fe4777dd9475fa70e87b8ff2efe3de74b7 3067 3066 2023-06-06T18:14:33Z Tchan 166 TOC cleanup wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) * Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) * (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) * Create a new subfolder ".vscode" * insert the following files in the ".vscode" subfolder: TODO: c_cpp_properties.json, kos_compile.sh, settings.json === Debugging on a real Dreamcast === TODO === Debugging on an emulator === TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 45dd93fd6b31e5b2df76d3a0710a81b0f1f58bf9 3068 3067 2023-06-06T18:18:28Z Tchan 166 TOC cleaning for the debugging part wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) * Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) * (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) * Create a new subfolder ".vscode" * insert the following files in the ".vscode" subfolder: TODO: c_cpp_properties.json, kos_compile.sh, settings.json === Debugging === TODO ==== With a real Dreamcast ==== ==== With an emulator ==== TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 96ad9e2279b1581ae744a645f44146a4aaabdcfa 3069 3068 2023-06-06T18:36:53Z Tchan 166 added compilation setup files wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_compile.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === TODO ==== With a real Dreamcast ==== ==== With an emulator ==== TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 70c0987e8b93dfd2e2146f2d470c0aa179ac26fd 3070 3069 2023-06-06T18:37:47Z Tchan 166 fix ref to kos_environ.sh file wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === TODO ==== With a real Dreamcast ==== ==== With an emulator ==== TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> e5c0d4531d127fc1c2f0ace152fc0dfcfad9122b 3071 3070 2023-06-06T18:50:59Z Tchan 166 /* Debugging */ starting to add debug info wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * TODO ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 52d721a56d8b7f4db273c9185948bc1659daed28 3073 3071 2023-06-06T19:01:20Z Tchan 166 Tchan moved page [[Visual Studio Code Debugging]] to [[Visual Studio Code]]: rename (removal of "debugging") wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * TODO ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 52d721a56d8b7f4db273c9185948bc1659daed28 3075 3073 2023-06-06T19:15:12Z Tchan 166 /* With a real Dreamcast */ added KOS_LOADER info wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a Broadband or LAN adapter: '''dcload-ip''' # via a serial cable & the serial port of the Dreamcast: '''dcload-serial''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> c1da65a9a7bf0433a8033e7269455a28273caff9 3076 3075 2023-06-06T19:18:19Z Tchan 166 /* With a real Dreamcast */ added hyperlinks to BBA/LAN adapter & coders cable wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''dcload-ip''' # via a [https://dreamcast.wiki/Coder%27s_cable serial cable] & the serial port of the Dreamcast: '''dcload-serial''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 541446ffeef6844886305cb21395da6bd1bea725 3077 3076 2023-06-06T19:23:51Z Tchan 166 /* With a real Dreamcast */ added links to dcload-ip & dcload-serial wikitext text/x-wiki This is a guide to setup your Visual Studio Code project with debugging support on both real hardware using [[dcload-ip]] and with the lxdream-nitro emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable serial cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> f94240f078e1cfdf3c999338a360b3d928f7d82d 3078 3077 2023-06-06T19:32:00Z Tchan 166 added lxdream link wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both real hardware using [[dcload-ip]] and with the [https://dreamcast.wiki/Dreamcast_emulators#lxdream lxdream-nitro emulator]. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable serial cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 4dde3f03042bd4530fc44684bad0d15866dfd5d0 3082 3078 2023-06-07T17:22:34Z Tchan 166 misc small changes + image of .vscode folder wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make" } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 5cdda902297e0087e59128455f14453473093ba1 3083 3082 2023-06-07T17:36:03Z Tchan 166 added kos-bash wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 96ed604a4c5675368a033cae8817ea6b1baf4d72 3084 3083 2023-06-07T17:50:47Z Tchan 166 added how to test compilation wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the ".vscode" subfolder: * c_cpp_properties.json <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> * kos_environ.sh <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * settings.json <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie /opt/toolchains/dc/sh-elf/bin/sh-elf-gdb should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a .vscode/launch.json file. You can add as many debugging configurations as you want inside that launch.json file. TODO ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -g -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -g -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 698f51a8a90e108394fb7b5f19aa33e33f621323 3085 3084 2023-06-07T19:41:18Z Tchan 166 added launch.json for debugging on real hardware wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''c_cpp_properties.json''' <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following file in the '''".vscode" subfolder''': '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "KOS debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 7a642755ffecf271fe6d2676dd3848a0cbb60504 3086 3085 2023-06-07T19:58:09Z Tchan 166 extra TOC entries for the compilation part wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''c_cpp_properties.json''' <syntaxhighlight lang="json"> { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "defines": [ "_arch_dreamcast" ], "compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}", } ], "version": 4 } </syntaxhighlight> * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== TODO ? make run ? === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following file in the '''".vscode" subfolder''': '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "KOS debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 9a46cef9862f292b1fc2439f6dbb186a057d64d1 3087 3086 2023-06-07T20:18:11Z Tchan 166 removed c_cpp_properties.json, settings.json covers that now wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_compile.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== TODO ? make run ? === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following file in the '''".vscode" subfolder''': '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "KOS debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 7647e435a66451990b5d308c66ee54641fc04d20 3088 3087 2023-06-07T20:23:58Z Tchan 166 fixed name of preconfigure script wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== TODO ? make run ? === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following file in the '''".vscode" subfolder''': '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "KOS debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in /opt/toolchains/dc/kos/environ.sh is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 1575e197d320e38b57891c7785185bc52e2ffb67 3089 3088 2023-06-07T20:47:37Z Tchan 166 added info about make run wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.0.2): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.0.2 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following file in the '''".vscode" subfolder''': '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "KOS debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 5646e30933b9a3a9265bc565d43156d234884808 3090 3089 2023-06-07T21:03:19Z Tchan 166 added launch config for dc-tool-ser wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.200): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.200 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following file in the '''".vscode" subfolder''': '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: add launch.json ==== With an emulator ==== * TODO == Setup Build Tasks (Optional) == This is an option step as you are able to just specify and launch ELFs. Setting up a build task in VSCode will allow your code to rebuild before launching the debug session. Use the following template to create your own .vscode/tasks.json file: <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> 4c1e6579baad8201a09de346922e298c16502491 3091 3090 2023-06-07T21:11:48Z Tchan 166 cleaning the tasks.json part wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.200): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.200 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: add launch.json ==== With an emulator ==== * TODO == Setup lxdream-nitro Launch Task == Setup a launch configuration for lxdream-nitro in your .vscode/launch.json file: <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { // display name "name": "LXDream", "type": "cppdbg", "request": "launch", // match build task name in tasks.json "preLaunchTask": "Build", "cwd": "${workspaceRoot}", // path to elf "program": "${workspaceRoot}/hello.elf", // path to gdb "miDebuggerPath": "PATH_TO_GDB", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true }, ] } </syntaxhighlight> e994e670b15a7063201a8877ed8ef1789240d18e 3092 3091 2023-06-07T21:24:54Z Tchan 166 merged LXDream launch.json with BBA/serial launch.json wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.200): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.200 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! === Debugging === * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceRoot}/hello.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: add launch.json ==== With an emulator ==== * TODO 3ea18ae76dc3c5c6a4982afb73a7a78311f80b6f 3093 3092 2023-06-07T21:28:10Z Tchan 166 change TOC of Debugging part wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.200): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.200 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceRoot}/hello.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: explain the steps ==== With an emulator ==== * TODO: explain the steps 920c8fac9ffd82510e4acbef9e1b6ff518eaa4ec Visual Studio Code Debugging 0 1385 3074 2023-06-06T19:01:20Z Tchan 166 Tchan moved page [[Visual Studio Code Debugging]] to [[Visual Studio Code]]: rename (removal of "debugging") wikitext text/x-wiki #REDIRECT [[Visual Studio Code]] 893cc1f83fec52841ef7b0a473a9ba636684f836 File:Vscode config files.png 6 1386 3080 2023-06-07T17:16:47Z Tchan 166 wikitext text/x-wiki configuration files in the .vscode folder bba9a79eac35d8164c00be1d8b3bee9db1f60535 File:Vscode cfg files.png 6 1387 3081 2023-06-07T17:21:25Z Tchan 166 wikitext text/x-wiki vscode_cfg_files.png 9fad0ee75b9a997ecbb3f2bf3e1a6405c20f3276 Visual Studio Code 0 768 3100 3093 2023-06-08T15:00:35Z Tchan 166 starting to note down what to add to the debugging part wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.200): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.200 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceRoot}/hello.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: explain the steps * TODO: add gdb_init(); with breakpoint, and conditional include ? * TODO: be sure to recompile after adding gdb_init * TODO: be sure to not put breakpoint before gdb_init ==== With an emulator ==== * TODO: explain the steps 508ce87090a328e4a86b641a0669783f59b41d86 3101 3100 2023-06-08T19:33:20Z Tchan 166 improving launch.json output console wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * (required) Install the following extensions: (Menu: View-Extensions) # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # [https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "makefile.alwaysPreConfigure": true, "makefile.preConfigureScript": ".vscode/kos_environ.sh", "makefile.makePath": "make", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Makefile: Build the current target", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.200): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.200 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "make", "args": [ "all" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.200 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": false, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "program": "${workspaceFolder}/${fileBasenameNoExtension}.elf", "cwd": ".", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${fileBasenameNoExtension}.elf", "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "filterStdout": false, // (default=true) "logging": { //Optional flags to determine what types of messages should be logged to the Debug Console. "exceptions": true, //exception messages "moduleLoad": true, //module load events "programOutput": true, //program output "engineLogging": true, //diagnostic engine logs "trace": false, //diagnostic adapter command tracing "traceResponse": true //diagnostic adapter command and response tracing } }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceRoot}/hello.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/hello.elf -n", "filterStdout": true, "filterStderr": true, "externalConsole": false, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> ==== With a real Dreamcast ==== * TODO: explain the steps * TODO: add gdb_init(); with breakpoint, and conditional include ? * TODO: be sure to recompile after adding gdb_init * TODO: be sure to not put breakpoint before or on gdb_init();, it really should only be placed after that ==== With an emulator ==== * TODO: explain the steps 7be38c990db7cd792c0950ccbbc441ace94c6b61 3102 3101 2023-06-09T18:44:44Z Tchan 166 refactoring all the files & removing the makefile tools extension wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. ==== Launching a Debug session ==== * YTODO: explain the steps * TODO: add gdb_init(); with breakpoint, and conditional include ? * TODO: be sure to recompile after adding gdb_init * TODO: be sure to not put breakpoint before or on gdb_init();, it really should only be placed after that ==== With an emulator ==== * TODO: explain the steps 0ee36978a1adea6b17646375a252b28d98d7afbe 3103 3102 2023-06-09T18:55:58Z Tchan 166 wrote debugging steps wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ source] 7451fe64fb4f3b069b8031ec87f901427bdba406 3104 3103 2023-06-09T19:01:19Z Tchan 166 set kos-bash as default terminal profile wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ source] 35c7e0887f9a2bef838aa8a2116f8eb4e4ece308 3105 3104 2023-06-09T19:02:34Z Tchan 166 cleaned indenting of settings.json wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ source] ec855d3807cdaad0781933af83f0b5645f4aa5ad 3106 3105 2023-06-09T19:03:38Z Tchan 166 added TODO rewrite default shell wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. (TODO: rewrite since kos-bash is the default shell now) ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ source] c809d62200f5b5449af00a21a537d5d6c5a582f9 3107 3106 2023-06-09T19:21:51Z Tchan 166 added sources topic with links to original articles wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. (TODO: rewrite since kos-bash is the default shell now) ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> ==== Sources ==== [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 916d7a55d5e8d5832fe8b10e86306b4306a70345 3108 3107 2023-06-09T19:22:32Z Tchan 166 changed toc level of "Sources" wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. (TODO: rewrite since kos-bash is the default shell now) ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> * Power on your dreamcast, with the dcload disc * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 4b2deb672c26d9b15aa45647cce8221bc0a06765 3109 3108 2023-06-09T20:10:54Z Tchan 166 added emulator option to make run wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. (TODO: rewrite since kos-bash is the default shell now) ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to send a program to a Dreamcast: # via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' # via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] bea5829aba94c62c9354036e625ec47753fb00d4 3110 3109 2023-06-09T20:14:41Z Tchan 166 added emulator to the "running a Dreamcast program" explanation wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project (Menu: File-Open Folder... eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix) # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. (TODO: rewrite since kos-bash is the default shell now) ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] f247d91b2af55c1cbc6e62d2bcef644b4cd62778 3112 3110 2023-06-11T10:29:48Z Tchan 166 adapted text to support WSL wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## If you are using WSL (Windows Subsystem for Linux), also install: ### [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you, so that you can run all Kallistios commands. (TODO: rewrite since kos-bash is the default shell now) ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. 2 extra steps are needed: * put a line to initialize gdb in your code: <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line. You can't put a breakpoint before or on this line ! ==== Launching a Debug session ==== * Launch your target (either dcload on your Dreamcast, or the emulator ? TODO) * Click on the "Debugger" icon (TODO: insert image) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream) * Click on the green arrow ("Start Debugging" - F5) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 288e1e7f507fbc6f0053aedaa30b81e54bfb251c 3114 3112 2023-06-11T10:46:16Z Tchan 166 adde screenshot for debugging & re-arranged the debugging text wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## If you are using WSL (Windows Subsystem for Linux), also install: ### [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 7efdbdf181494a0eabb08e8dbbd3a9aeaa2037c2 3115 3114 2023-06-11T10:54:39Z Tchan 166 /* Preparation */ wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## If you are using WSL (Windows Subsystem for Linux), also install: ### [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] ## TODO: add useful extensions # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] c9234db11c0800722f81bf725ef5054b1eef0d50 3116 3115 2023-06-11T10:55:51Z Tchan 166 /* VSCode Setup */ removed unnecessary TODO text wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## If you are using WSL (Windows Subsystem for Linux), also install: ### [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: TODO: replace image without c_cpp_properties.json {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 14e9f84b3e46528c08c7727fa245a6fe171f89c9 3118 3116 2023-06-11T11:00:07Z Tchan 166 /* Preparation */ removed TODO about updating an image wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Optional: ## If you are using WSL (Windows Subsystem for Linux), also install: ### [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 957b7bc29df0915d615b409fdbaf4375f5c6e87c 3119 3118 2023-06-11T15:53:03Z Tchan 166 /* VSCode Setup */ wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Required only if you are using WSL (Windows Subsystem for Linux): ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' (This makes sure that the code is compiled before launching the debug session) <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] ef37b3bc2fb4bc854f2562be2cafc3007440bce6 3120 3119 2023-06-11T15:54:38Z Tchan 166 /* Preparation */ wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Required only if you are using WSL (Windows Subsystem for Linux): ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 1ca49d88f2557cd34989355c9952666c8dcee881 3122 3120 2023-06-14T16:29:07Z Tchan 166 added tip about dbglog() wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Required only if you are using WSL (Windows Subsystem for Linux): ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> * '''tasks.json''' <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Tips ==== * If you want to print out the value of a variable to the console (Terminal) on the pc, add a line like this to your code: <syntaxhighlight lang="c"> dbglog(DBG_INFO, "value is: 0x%08X\n", variable); </syntaxhighlight> ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] bdfcc46ee33c0ec76c2087c584f8bffd278a4c8a 3123 3122 2023-06-14T16:31:51Z Tchan 166 TODO added for terminal.integrated.*.osx wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Required only if you are using WSL (Windows Subsystem for Linux): ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/include", "/opt/toolchains/dc/kos/kernel/arch/dreamcast/include", "/opt/toolchains/dc/kos/addons/include", "/opt/toolchains/dc/kos-ports/include" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> (TODO: to be tested for Mac/OSX: probably needs the 2 lines terminal.integrated.*.linux replaced with terminal.integrated.*.osx) * '''tasks.json''' <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Tips ==== * If you want to print out the value of a variable to the console (Terminal) on the pc, add a line like this to your code: <syntaxhighlight lang="c"> dbglog(DBG_INFO, "value is: 0x%08X\n", variable); </syntaxhighlight> ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 46a0c83d2fc3fc07d6e09241f39eec96d4c3cee5 3124 3123 2023-06-15T06:09:37Z Tchan 166 /* Preparation */ Simplified C_Cpp.default.includePath so that all kos & kos-port function definitions can be accessed wikitext text/x-wiki This is a guide to setup your [https://code.visualstudio.com/ Visual Studio Code] project with debugging support on both on a real Dreamcast and with an emulator. == Prerequisites == To start with, this tutorial makes the following assumptions: * You have already installed and [https://dreamcast.wiki/Getting_Started_with_Dreamcast_development set up your KallistiOS development environment]] # if you want to be able to debug, be sure to compile gdb as specified on that page * You have already downloaded and installed [https://code.visualstudio.com/ Visual Studio Code] (version 1.78.2 was used for this tutorial) == VSCode Setup == * Launch Visual Studio Code * (optional but recommended) To keep your configuration settings, plugins, ... specific to Dreamcast projects only: # Create a "Profile" (Menu: File-Preferences-Profiles) called "Dreamcast" * Install the following extensions: (Menu: View-Extensions) # Required: ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools C/C++] from Microsoft # Required only if you are using WSL (Windows Subsystem for Linux): ## [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl WSL from Microsoft] # (Not recommended at this moment:) ## ([https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools Makefile Tools] from Microsoft: the current version (June 2023) is not really adapted for remote debugging) == Setup per Project == === Compilation === ==== Preparation ==== (all the following steps happen in Visual Studio Code) # Open the folder containing your project - eg: /opt/toolchains/dc/kos/examples/dreamcast/2ndmix: ##If you are using WSL: ###"F1" - "Connect To WSL" ##Menu: File-Open Folder... # (if you are using Profiles) Make sure that the "Dreamcast" profile is selected (Menu: File-Preferences-Profiles) #If you are using WSL, check that the C/C++ extension is correctly installed for WSL - if you get a warning like "install in WSL: Ubuntu", do so. # Create a new subfolder ".vscode" # insert the following files in the '''".vscode" subfolder''': * '''kos_environ.sh''' <syntaxhighlight lang="bash"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh </syntaxhighlight> * '''kos_make.sh''' <syntaxhighlight lang="json"> #!/bin/bash #set the KOS environtment variables source /opt/toolchains/dc/kos/environ.sh make exit </syntaxhighlight> * '''settings.json''' <syntaxhighlight lang="json"> { "C_Cpp.default.includePath": [ "${workspaceFolder}/**", "/opt/toolchains/dc/kos/**", "/opt/toolchains/dc/kos-ports/**" ], "C_Cpp.default.defines": [ "_arch_dreamcast" ], "C_Cpp.default.compilerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc", "C_Cpp.default.cStandard": "c11", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.intelliSenseMode": "", "terminal.integrated.defaultProfile.linux": "kos-bash", "terminal.integrated.profiles.linux": { "kos-bash": { "path": "/usr/bin/bash", "args": ["--init-file", "${workspaceFolder}/.vscode/kos_environ.sh" ], "overrideName": true } } } </syntaxhighlight> (TODO: to be tested for Mac/OSX: probably needs the 2 lines terminal.integrated.*.linux replaced with terminal.integrated.*.osx) * '''tasks.json''' <syntaxhighlight lang="json"> { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "process", "command": "bash", "args": [ "--init-file", "${workspaceFolder}/.vscode/kos_make.sh" ], "group": { "kind": "build", "isDefault": true }, }, ] } </syntaxhighlight> The result should look like this: {| | [[File:Vscode cfg files.png|thumb]] |} At this point, you should be able to compile applications for the Dreamcast! ==== Compilation ==== You can compile via 2 ways: # via the VSCode [https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette Command Palette] - "Tasks: Run Build Task", or # by opening a "kos-bash" terminal (Menu: View-Terminal if not visible yet, then click on the "+" to see the terminals to choose from, and select "kos-bash"), and typing "make" In both cases, the compilation should generate an executable file, ending with .elf Note: "kos-bash" is a bash shell with the "source /opt/toolchains/dc/kos/environ.sh" already executed for you. It should be your default shell in VSCode as long as you used the settings.json mentioned above. ==== Running a program ==== For this, we will use the "make run" command that you can find in many (all?) Makefiles of the KallistiOs project, to send and run the program on a real dreamcast: * Typically, one of the following tools is used to run a program for the Dreamcast: # on a real Dreamcast: ##via an ethernet cable & a [https://dreamcast.wiki/Broadband_adapter Broadband] (BBA) or [https://dreamcast.wiki/LAN_adapter LAN] adapter: '''[https://dreamcast.wiki/Dcload-ip dcload-ip]''' ## via a [https://dreamcast.wiki/Coder%27s_cable coder's cable] & the serial port of the Dreamcast: '''[https://dreamcast.wiki/Dcload-serial dcload-serial]''' # on an emulator, like lxdream-nitro * Make sure that the '''KOS_LOADER''' variable in '''/opt/toolchains/dc/kos/environ.sh''' is configured correctly: # for '''dcload-ip''' (example if the IP of the Dreamcast is 192.168.1.210): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ip -t 192.168.1.210 -x" </syntaxhighlight> # for '''dcload-serial''' (example if the Dreamcast is on serial port /dev/ttyS0): <syntaxhighlight lang="bash"> export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x" </syntaxhighlight> # for '''the emulator''' (example with lxdream-nitro): <syntaxhighlight lang="bash"> export KOS_LOADER="/opt/toolchains/dc/lxdream-nitro/builddir/lxdream-nitro -e" </syntaxhighlight> * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Open a "kos-bash" terminal, and type: make run * The program will be running on your Dreamcast or on the emulator ! * (If you ran the 2ndmix example, you can press the START button on the Dreamcast pad to exit) * Note: be sure to not have a gdb_init(); line added in your code when you only want to run a program & not debug it. === Debugging === ==== Preparation ==== * Make sure that you compiled gdb for the Dreamcast, ie '''/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb''' should exist (cfr prerequisites) * Debugging in Visual Studio Code is configured in a '''.vscode/launch.json''' file. You can add as many debugging configurations as you want inside that launch.json file, eg 1 for debugging on a dreamcast, 1 for debugging on an emulator, ... # insert the following files in the '''".vscode" subfolder''': * '''launch.json''' (example with the IP of the Dreamcast = 192.168.1.210 for the BBA/LAN or /dev/ttyS0 for the serial cable): <syntaxhighlight lang="json"> { "version": "0.2.0", "configurations": [ { "name": "BBA_LAN", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ip, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ip", "debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t 192.168.1.210 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "SERIAL", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "MIMode": "gdb", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress":"localhost:2159",//common misconception: we connect to the gdb server offered by dc-tool-ser, NOT to the Dreamcast directly ! "debugServerPath":"/opt/toolchains/dc/bin/dc-tool-ser", "debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/${workspaceFolderBasename}.elf", //"debugServerArgs": "-g -t /dev/ttyS0 -x ${workspaceFolder}/2ndmix.elf", //"stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", }, { "name": "LXDream", "type": "cppdbg", "request": "launch", "preLaunchTask": "Build", "cwd": "${workspaceRoot}", "program": "${workspaceFolder}/${workspaceFolderBasename}.elf", //"program": "${workspaceFolder}/2ndmix.elf", "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "setupCommands": [{ "text": "set architecture sh", "description": "Set GDB Arch to SuperH", "ignoreFailures" : false, }], "miDebuggerServerAddress": ":9999", // path to lxdream-nitro "debugServerPath": "PATH_TO_LXDREAM", // lxdream-nitro flags "debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/${workspaceFolderBasename}.elf -n", //"debugServerArgs": "--log=DEBUG --gdb-sh4=9999 -A null -e ${workspaceRoot}/2ndmix.elf -n", "filterStdout": true, "filterStderr": true, // run on connect "stopAtConnect": false, // stop at main "stopAtEntry": true, "externalConsole": false, "avoidWindowsConsoleRedirection": false, "internalConsoleOptions": "openOnSessionStart", "launchCompleteCommand": "exec-run", "serverStarted": "SH4 GDB server running on port", "useExtendedRemote": true } ] } </syntaxhighlight> Note that for the 3 launch configurations above, you have 2 lines for "program" and "debugServerArgs", one of which is commented out. ${workspaceFolderBasename} is the name of your project directory (eg: 2ndmix), and if that matches the name of your target .elf file (eg: 2ndmix.elf), then you can use ${workspaceFolderBasename}. If not, you can just use the other line by replacing ${workspaceFolderBasename} with the real .elf filename. You'll also need to replace "PATH_TO_LXDREAM" with the path to the emulator installed on your pc. ==== Launching a Debug session ==== {| | [[File:Vscode debugging.png|thumb|alt=Vscode debugging|Vscode debugging]] |} * put a line to initialize gdb in your code (1): <syntaxhighlight lang="c"> gdb_init(); </syntaxhighlight> TODO: conditional include * insert a breakpoint '''AFTER''' this gdb_init(); line (1). You can't put a breakpoint before or on this line ! * If want to run it on a real Dreamcast, power it on with the dcload disc loaded, and wait for the blue screen * Click on the "Debugger" icon (2) on the left * Select the configuration you want to launch (BBA_LAN, SERIAL, or LXDream)(3) * Click on the green arrow ("Start Debugging" - F5)(4) ==== Tips ==== * If you want to print out the value of a variable to the console (Terminal) on the pc, add a line like this to your code: <syntaxhighlight lang="c"> dbglog(DBG_INFO, "value is: 0x%08X\n", variable); </syntaxhighlight> ==== Troubleshooting Tips ==== * If the dc-tool app does not seem to react anymore: <syntaxhighlight lang="bash"> sudo netstat -ap | grep :2159 sudo kill <pid> </syntaxhighlight> == Sources == [https://forums.sonicretro.org/index.php?threads/setting-up-gdb-with-redream-in-linux.38824/ netstat tip source] [https://dcemulation.org/phpBB/viewtopic.php?t=105596&start=20 Original VSCode topic on dcemulation.org] 3339cd5cc004dce87cafcec0b771407632cfc716 Getting Started with Dreamcast development 0 694 3111 3079 2023-06-11T10:18:07Z Tchan 166 /* Debian/Ubuntu-based Linux */ added sudo apt-get update (without that, WSL has problems with the dependencies) wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2022-12-17.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. a8ffda29f1cc9f1f784016d3d55566884d9eb4cf 3129 3111 2023-06-24T23:27:08Z Darc 1 /* Running an example program through a debug link */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.2.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. 7d8d19aba4dd5a9d738ec320b539958632133271 File:Vscode debugging.png 6 1388 3113 2023-06-11T10:43:16Z Tchan 166 wikitext text/x-wiki Vscode debugging ee3e22a503f500381bdc3246adb817893474649a File:Vscode cfg files.png 6 1387 3117 3081 2023-06-11T10:58:59Z Tchan 166 Tchan uploaded a new version of [[File:Vscode cfg files.png]] wikitext text/x-wiki vscode_cfg_files.png 9fad0ee75b9a997ecbb3f2bf3e1a6405c20f3276 File Types 0 1389 3121 2023-06-13T20:15:32Z BBHoodsta 2 Created page with "Author: Andress Barajas = Introduction = This guide will focus on file types that are associated with the Visual Memory Unit '''(VMU)'''. The files types covered in this guide are '''.VMI''' '''.VMS''' and '''.DCI'''. First, some facts about the storage specs of the '''VMU''': # Officially has 200 blocks of free storage space where each block is 512 bytes. Files saved to the '''VMU''' take up a number of blocks so the file size is always a multiple of 512 bytes. # Can..." wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus on file types that are associated with the Visual Memory Unit '''(VMU)'''. The files types covered in this guide are '''.VMI''' '''.VMS''' and '''.DCI'''. First, some facts about the storage specs of the '''VMU''': # Officially has 200 blocks of free storage space where each block is 512 bytes. Files saved to the '''VMU''' take up a number of blocks so the file size is always a multiple of 512 bytes. # Can only store one vmu game per '''VMU''' at one time. # You can unlock 41 more blocks of storage by running this code here(include link) = VMI = Visual Memory Information File or '''VMI''' is just a link-type file that sits on a web server and is not stored/saved on the VMU at all. If you were to try and download a file with this extension using a web browser on the dreamcast, you will instead download a .VMS with the filename located at offset $58 to your '''VMU'''. === File Header === Source: <ref>http://mc.pp.se/dc/vms/vmi.html</ref> {| class="wikitable" style="text-align: center" |- ! scope="col"| Offset ! scope="col"| Size (bytes) ! scope="col"| Datatype ! scope="col"| Contents |- | $00 | 4 | Integer |style="text-align: left;"| Checksum |- | $04 | 32 | Text |style="text-align: left;"| Description |- | $24 | 32 | Text |style="text-align: left;"| Copyright |- | $44 | 2 | Integer |style="text-align: left;"| Creation Year |- | $46 | 1 | Integer |style="text-align: left;"| Creation month (1-12) |- | $47 | 1 | Integer |style="text-align: left;"| Creation day (1-31) |- | $48 | 1 | Integer |style="text-align: left;"| Creation hour (0-23) |- | $49 | 1 | Integer |style="text-align: left;"| Creation minute (0-59) |- | $4A | 1 | Integer |style="text-align: left;"| Creation second (0-59) |- | $4B | 1 | Integer |style="text-align: left;"| Creation weekday (0=sunday-6=saturday) |- | $4C | 2 | Integer |style="text-align: left;"| VMI version (set to 0) |- | $4E | 2 | Integer |style="text-align: left;"| File number (set to 1) |- | $50 | 8 | Text |style="text-align: left;"| .VMS resource name (without the .VMS) |- | $58 | 12 | Text |style="text-align: left;"| '''Filename''' (on the VMS) |- | $64 | 2 | Integer | style="text-align: left;"| File mode bitfield ('''see table below''') |- | $66 | 2 | Integer |style="text-align: left;"| ? (set to 0) |- | $68 | 4 | Integer |style="text-align: left;"| File size in bytes |} '''File mode bitfield''': {| class="wikitable" style="text-align: center" |- ! scope="col"| 15..2 ! scope="col"| 1 ! scope="col"| 0 |- | ''not used'' | GAME (1=game, 0=data) | PROTECT (1=copy protected, 0=copy ok) |} = VMS = Visual Memory System File or '''VMS''' is a data-type file that contains either a game save, a vmu game, or special data (See '''EXTRA.BG.PVR''' and '''ICONDATA_VMS''' below). === File Header === Source: <ref>http://mc.pp.se/dc/vms/fileheader.html</ref> {| class="wikitable" style="text-align: center" |- ! scope="col"| Offset ! scope="col"| Size (bytes) ! scope="col"| Datatype ! scope="col"| Contents |- | $00 | 16 | Text |style="text-align: left;"| Description of file (shown in VMS file menu) |- | $10 | 32 | Text |style="text-align: left;"| Description of file (shown in DC boot ROM file manager) |- | $30 | 16 | String |style="text-align: left;"| Identifier of application that created the file |- | $40 | 2 | Integer |style="text-align: left;"| Number of icons (>1 for animated icons) |- | $42 | 2 | Integer |style="text-align: left;"| Icon animation speed |- | $44 | 2 | Integer |style="text-align: left;"| Graphic eyecatch type (0 = none) |- | $46 | 2 | Integer |style="text-align: left;"| CRC (Ignored for game files.) |- | $48 | 4 | Integer |style="text-align: left;"| Number of bytes of actual file data following header, icon(s) and graphic eyecatch. (Ignored for game files.) |- | $4C | 20 | |style="text-align: left;"| Reserved (fill with zeros) |- | $60 | 32 | Integers |style="text-align: left;"| Icon palette (16 16-bit integers) |- | $80 | 512*n | Nybbles |style="text-align: left;"| Icon bitmaps |- | ... | depends on type | ... |style="text-align: left;"| Graphic eyecatch palette and bitmap |} === EXTRA.BG.PVR === # VMS Data file with pvr inside # Not shown in DC Boot ROM file manager # Used as sky texture during the bios menus === ICONDATA_VMS === # Not shown in DC Boot ROM file manager # Hold Monochrome(vmu) and palette image (DC File manager) Include screen shots # ALTERNATE 3D Bios Menu if at offset 0x2c0: DA 69 D0 DA C7 4E F8 36 18 92 79 68 2D B5 30 86 # Press start to switch over to a 30fps mode with light source shaded models. Can press start again to switch back. = DCI = = Unlock 41 extra blocks = <syntaxhighlight lang="c" line="line"> // Increase to 241 blocks { vmu_root_t root; if(vmufs_root_read(dev, &root) < 0) return -1; root.blk_cnt = 241; if(vmufs_root_write(dev, &root) < 0) return -1; } </syntaxhighlight> = Sources = d0be331c2680ace7749d797345ee5a767eda7cdb Libronin 0 167 3125 3058 2023-06-23T16:30:28Z Darc 1 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++. # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to skip copying KOS Newlib headers into toolchain And finally, download and build the toolchain. make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> and <code>zlib/Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 107488dff0da2f9dba0e9f047c0d5f1c3b705d1f 3126 3125 2023-06-23T16:30:39Z Darc 1 /* Building a toolchain for libronin */ wikitext text/x-wiki libronin is a software development library similar to [[KallistiOS]]. It was developed by [[Marcus Comstedt]], [[Peter Bortas]] and [[Per Hedbor]]. It is used in [[DreamSNES]], [[ScummVM]], and [[Cave Story]]. It is primarily known for its use in projects by Marcus Comstedt and [[histat]]. ==Projects using libronin== * [[Cave Story]] * [[DreamSNES]] * [[Neko Project II]] * [[ScummVM]] * [[X Millennium]] ==Release history== libronin's latest release was in 2016.<ref>''[http://dcevolution.sourceforge.net/index.php?id=libronin], Libronin | DC Evolution - The Dreamcast Resource''</ref> * Libronin 0.1 (2002-02-03) * Libronin 0.2 (2002-02-27) * Libronin 0.3 (2002-04-21) * Libronin 0.4 (2003-05-04) * Libronin 0.5 (2008-01-01) * Libronin 0.6 (2016-09-26) ==Building a toolchain for libronin== The standard [[KallistiOS]] sh-elf toolchain contains patches that prevent it from working with libronin; however, KallistiOS's <code>dc-chain</code> script can be used to easily build a libronin-compatible raw toolchain. You can build this toolchain to a separate directory than an existing KallistiOS toolchain. Create a directory to hold the toolchain and give yourself ownership: sudo mkdir -p /opt/toolchains/dc/roninchain sudo chown -R $USER:$USER /opt/toolchains/dc/roninchain Clone the KallistiOS repo somewhere convenient: git clone https://github.com/KallistiOS/KallistiOS.git kos Enter the toolchain directory: cd kos/util/dc-chain Copy over one of the default configuration files: cp config.mk.sample.testing config.mk Open <code>config.mk</code> in a text editor and edit the following lines. toolchains_base=/opt/toolchains/dc/roninchain # Where you want to install the toolchain pass2_languages=c,c++ # Which languages you want to build support for thread_model=single # support only for single threads use_kos_patches=0 # Set this 0 to ensure raw toolchain with no patches auto_fixup_sh4_newlib=0 # Set this 0 to skip copying KOS Newlib headers into toolchain And finally, download and build the toolchain. make You can now use the compilers stored at <code>/opt/toolchains/dc/roninchain/sh-elf/bin</code> and <code>/opt/toolchains/dc/roninchain/arm-eabi/bin</code> to compile libronin. You may need to modify <code>Makefile</code> and <code>zlib/Makefile</code> included with libronin to include the path to the compilers. You may delete the <code>kos</code> folder that you cloned using git earlier once your toolchain is successfully installed. ==Source== *[https://bitbucket.org/ihi/libronin/src libronin source code repository on Bitbucket] ==References== <references/> {{DISPLAYTITLE:libronin}} 364d9a890ea01fa1b51e5de20914391b8db9a830 File:Dead or alive2.gif 6 1390 3127 2023-06-23T18:28:09Z GyroVorbis 13 wikitext text/x-wiki Fancy Effects from Dead or Alive 2 175b49b41da5250aa4ae584c2b4b0196d6ed7a20 File:Dcload-2023-06-22.zip 6 1391 3128 2023-06-24T23:25:32Z Darc 1 Uploaded own work with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=discjuggler images for dcload-ip 2.0.1 and dcload-serial 1.0.6, the latest versions as of 2023-06-22}} |date=2023-06-22 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d5a02cdc242f625b63f43a58821547d5bd5ee528 Dcload-ip 0 23 3130 1522 2023-06-24T23:27:54Z Darc 1 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. The program is mostly intended for homebrew development, but can also be used with special programs designed to make use of it like [https://github.com/zeldin/dc-virtcd Marcus Comstedt's dc-virtcd]. [[:File:Dcload-2023-06-22.zip|Download the latest versions of dcload-ip 2.0.1 and dcload-serial 1.0.6 as of June 22, 2023]] '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip main repository] - maintained by SiZiOUS {{DISPLAYTITLE:dcload-ip}} ac4a2d5a811406a313768a52a42138e4e66778b0 3133 3130 2023-06-24T23:28:41Z Darc 1 wikitext text/x-wiki dcload-ip is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a [[Broadband adapter]] or [[LAN adapter]] as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the [[BIOS modification|BIOS]]. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the BBA. It also provides chainloaded programs with a standard syscall interface for communicating with a networked PC. The program is mostly intended for homebrew development, but can also be used with special programs designed to make use of it like [https://github.com/zeldin/dc-virtcd Marcus Comstedt's dc-virtcd]. [[:File:Dcload-2023-06-22.zip|Download the latest DiscJuggler images with versions of dcload-ip 2.0.1 and dcload-serial 1.0.6 as of June 22, 2023]] '''Sources''' * [https://github.com/sizious/dcload-ip dcload-ip main repository] - maintained by SiZiOUS {{DISPLAYTITLE:dcload-ip}} 94911f68097593c01e3f0da11fbc266af574f2af Dcload-serial 0 698 3131 1523 2023-06-24T23:28:23Z Darc 1 wikitext text/x-wiki dcload-serial is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a serial cable as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the BIOS. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the serial port. It also provides chainloaded programs with a standard syscall interface for communicating with a connected PC. The program is mostly intended for homebrew development, but can also be used with special programs. [[:File:Dcload-2023-06-22.zip|Download the latest DiscJuggler images with versions of dcload-ip 2.0.1 and dcload-serial 1.0.6 as of June 22, 2023]] [https://github.com/sizious/dcload-serial dcload-serial main repository] - maintained by SiZiOUS {{DISPLAYTITLE:dcload-serial}} 4ded867f55543ecf67598ba829cb82c9599cadba 3132 3131 2023-06-24T23:28:30Z Darc 1 wikitext text/x-wiki dcload-serial is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a serial cable as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the BIOS. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the serial port. It also provides chainloaded programs with a standard syscall interface for communicating with a connected PC. The program is mostly intended for homebrew development, but can also be used with special programs. [[:File:Dcload-2023-06-22.zip|Download the latest DiscJuggler images with versions of dcload-ip 2.0.1 and dcload-serial 1.0.6 as of June 22, 2023]] [https://github.com/sizious/dcload-serial dcload-serial main repository] - maintained by SiZiOUS {{DISPLAYTITLE:dcload-serial}} ff79cadc4de18142b63998166ae949d2e1648d58 3146 3132 2023-07-03T21:14:40Z Tchan 166 added link to Coder's Cable page, and KallistiOs github link to dcload-serial wikitext text/x-wiki dcload-serial is a homebrew program originally developped by Andrew Kieschnick. It allows a developer to use a serial cable (aka [[Coder's cable]]) as a link to send, execute, and debug code on a Sega Dreamcast console. It is typically loaded via CD-R, but can also be loaded directly through the BIOS. It is able to transfer .bin and .elf files (and srec files, if specially configured for it) over the serial port. It also provides chainloaded programs with a standard syscall interface for communicating with a connected PC. The program is mostly intended for homebrew development, but can also be used with special programs. [[:File:Dcload-2023-06-22.zip|Download the latest DiscJuggler images with versions of dcload-ip 2.0.1 and dcload-serial 1.0.6 as of June 22, 2023]] [https://github.com/KallistiOS/dcload-serial new dcload-serial main repository] - maintained by the KallistiOS community (outdated - [https://github.com/sizious/dcload-serial dcload-serial main repository] - maintained by SiZiOUS ) {{DISPLAYTITLE:dcload-serial}} ce54d6149c95a50afcd31907cf7502dfcaf1d5a0 Coder's cable 0 90 3134 275 2023-06-30T11:40:01Z Tchan 166 added baud rates for the coder's cable wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). - Using the Dreamcast's clock: * These baud rates should work with most systems/cables: 38400, 57600, 115200, 230400. (eg: lik-sang cable) * These baud rates need a good cable: 500000, 781250, 1500000. (eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable] * Specifying non-standard baud rates like 781250 might be tricky/impossible for most programs. This should work: ** picocom -b 781250 -d 8 -y n -p 1 /dev/ttyUSB0 - Using an external clock (SCK pin): (TODO) {{DCWiki:Stub}} cd4a1e66ad5990cee828f35d92600a4344d07192 3135 3134 2023-06-30T11:40:16Z Tchan 166 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). - Using the Dreamcast's clock: * These baud rates should work with most systems/cables: 38400, 57600, 115200, 230400. (eg: lik-sang cable) * These baud rates need a good cable: 500000, 781250, 1500000. (eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable]) * Specifying non-standard baud rates like 781250 might be tricky/impossible for most programs. This should work: ** picocom -b 781250 -d 8 -y n -p 1 /dev/ttyUSB0 - Using an external clock (SCK pin): (TODO) {{DCWiki:Stub}} e994feed547680e0f3a42757faf2d78e87c51c93 3136 3135 2023-06-30T11:45:36Z Tchan 166 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). - Using the Dreamcast's clock: * These baud rates should work with most systems/cables: 38400, 57600, 115200, 230400. (eg: lik-sang cable) * These baud rates need a good cable: 500000, 781250, 1500000. (eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable]) * Specifying non-standard baud rates like 781250 might be tricky/impossible for most programs. Picocom for example accepts that value: ** picocom -b 781250 -d 8 -y n -p 1 /dev/ttyUSB0 - Using an external clock (SCK pin): (TODO) {{DCWiki:Stub}} 38c896da914278cc906dd33465099c75e7727830 3137 3136 2023-06-30T20:17:01Z Tchan 166 disclaimer added for high speeds wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). - Using the Dreamcast's clock: * These baud rates should work with most systems/cables: 38400, 57600, 115200, 230400. (eg: lik-sang cable) ** Note that 230400 does not work yet with the current dc-load-serial (1.0.6), but a fix is incoming * These baud rates need a good cable: 500000, 781250, 1500000. (eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], but even with those it's probably not a 100% guarantee) * Specifying non-standard baud rates like 781250 might be tricky/impossible for most programs. Picocom for example accepts that value: ** picocom -b 781250 -d 8 -y n -p 1 /dev/ttyUSB0 - Using an external clock (SCK pin): (TODO) {{DCWiki:Stub}} f60508aed26b7f126845d4f1c79fce2189290804 3138 3137 2023-07-03T14:27:51Z Tchan 166 wrote baudrate & chip recommendations, started howto build cable wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * Silicon Labs '''CP2102N''': ** under review, should support 1562500. How to build/buy a cable: * Buy: eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: cfr DC SD Adapter V2 ** select a usb-to-serial chip/cable, cfr recommended chips above ** connect TXD <-> RXD, RXD <-> TXD, RTS <-> CTS, CTS <-> RTS {{DCWiki:Stub}} a5b3ab7a9835d69a34826d16c83bcfd5490d69d4 3139 3138 2023-07-03T14:44:56Z Tchan 166 extra info on 230400 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400, otherwise use 223214 or 260416 ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * Silicon Labs '''CP2102N''': ** under review, should support 1562500. How to build/buy a cable: * Buy: eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: cfr DC SD Adapter V2 ** select a usb-to-serial chip/cable, cfr recommended chips above ** connect TXD <-> RXD, RXD <-> TXD, RTS <-> CTS, CTS <-> RTS {{DCWiki:Stub}} e4908eb732dc3ddfa41c9550b1c6e6689c77b567 3140 3139 2023-07-03T14:46:26Z Tchan 166 extra info on 230400 bis wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * Silicon Labs '''CP2102N''': ** under review, should support 1562500. How to build/buy a cable: * Buy: eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: cfr DC SD Adapter V2 ** select a usb-to-serial chip/cable, cfr recommended chips above ** connect TXD <-> RXD, RXD <-> TXD, RTS <-> CTS, CTS <-> RTS {{DCWiki:Stub}} eccb69efa2b78279cb27c395a75a2dc2599f654a 3141 3140 2023-07-03T14:46:54Z Tchan 166 extra info on 230400 ter wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * Silicon Labs '''CP2102N''': ** under review, should support 1562500. How to build/buy a cable: * Buy: eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: cfr DC SD Adapter V2 ** select a usb-to-serial chip/cable, cfr recommended chips above ** connect TXD <-> RXD, RXD <-> TXD, RTS <-> CTS, CTS <-> RTS {{DCWiki:Stub}} 3a9e84befbf4e5fc84a308847d5840592189064f 3142 3141 2023-07-03T16:39:16Z Tchan 166 cleaned up how to buy/build section, added ebay link for DC SD adapter V2 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * Silicon Labs '''CP2102N''': ** under review, should support 1562500. How to build/buy a cable: * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] ** select a usb-to-serial chip/cable *** cfr recommended chips above ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS {{DCWiki:Stub}} 67a77419e89bf8ec2eff8981204efd534301fce0 3144 3142 2023-07-03T17:06:45Z Tchan 166 added DC SD Adapter V2 image wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * Silicon Labs '''CP2102N''': ** under review, should support 1562500. How to build/buy a cable: * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable *** cfr recommended chips above ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS {{DCWiki:Stub}} cb1445d5e8f87bd4425b65bf4ddf66a65d543509 3145 3144 2023-07-03T20:55:42Z Tchan 166 added silicon labs urls and some price ideas wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: ** under review, should support 1562500. ** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] ** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] How to build/buy a cable: * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** cfr recommended chips above ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS {{DCWiki:Stub}} f693b2fd4455c144c520c81bf746cbc3776a026e 3147 3145 2023-07-03T21:16:33Z Tchan 166 added link to dcload-serial page wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) Recommended USB-Serial chips: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: ** under review, should support 1562500. ** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] ** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] How to build/buy a cable: * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** cfr recommended chips above ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS Software to use: [[Dcload-serial]] {{DCWiki:Stub}} 4a339a7b42a6270a641b6133be7d180bf335ff21 3148 3147 2023-07-03T21:19:04Z Tchan 166 added a TOC wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) == USB-Serial chips == Recommended: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: ** under review, should support 1562500. ** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] ** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** cfr recommended chips above ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] {{DCWiki:Stub}} e3731cb93535c506f711f4dec0caee56bba0f74e 3149 3148 2023-07-03T21:22:10Z Tchan 166 reordered paragraphs wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** cfr recommended chips above ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == USB-Serial chips == Recommended: * FDTI's '''FT232R'''-like chips: ** '''good until 781250''', does not support 1562500. ** 500000 and 1500000 will not work with all chips/on all pc. * [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: ** under review, should support 1562500. ** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] ** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} b268c003e5aa7e792a3a504d4582fc209e9bb8d3 File:DC SD Adapter V2.jpg 6 1392 3143 2023-07-03T17:04:29Z Tchan 166 wikitext text/x-wiki DC SD Adapter V2 76c5541316139c356b94df08d8aef21d29d4bebf Coder's cable 0 90 3150 3149 2023-07-03T21:25:24Z Tchan 166 merged chips section into how to build section wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc. *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** under review, should support 1562500. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] ** connect the following pins: *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 1cfcf012f9c253cab01fa5c64d0b81588e67563d 3151 3150 2023-07-03T21:28:32Z Tchan 166 added link to Serial_interface wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc. *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** under review, should support 1562500. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 19f68217521285fe9a965f77eff61fdedbc86bb2 3154 3151 2023-07-04T08:09:17Z Tchan 166 added DSD TECH Cable info wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc. *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** under review, should support 1562500. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 49aa7c7e74a39e823d8df88d8daf71423d3f0744 3155 3154 2023-07-04T08:43:35Z Tchan 166 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, and even if you're lucky, you won't really get 1500000-worthy speeds... *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** under review, should support 1562500. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} aab8e1f8815f8e5c913404e306a439ae2e6432b2 3156 3155 2023-07-04T15:04:41Z Tchan 166 corrected info on CP2102N's max baud speed, and added some indication as to attaignable speeds wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** under review, supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Early tests give speeds of 180-210 kByte/sec. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 5ef416ddf2214e533ecdf441123aeba82910f2e5 3157 3156 2023-07-04T19:29:41Z Tchan 166 adapted speed expectations CP2102N wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** under review, supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Early tests give speeds of 170-210 kByte/sec. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 27e455cec63254cf0fb0d85c544a5db3025798c0 3158 3157 2023-07-06T15:18:55Z Tchan 166 small corrections after final findings wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250 if combined with CP2102N-chip) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** Disclaimer for Linux only: Requires a patch to support custom speeds that is not yet part of dc-load-ser 1.0.6. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} e15363d7eef3a600256bb9802ee784090e4a6822 3159 3158 2023-07-06T16:31:10Z Tchan 166 added USB connector types to the CP2102N solutions wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250 if combined with CP2102N-chip) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** Disclaimer for Linux only: Requires a patch to support custom speeds that is not yet part of dc-load-ser 1.0.6. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 2981395b048843bf6bfb506df3300aaa932e4509 3160 3159 2023-07-06T16:31:28Z Tchan 166 wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250 if combined with CP2102N-chip) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** Disclaimer for Linux only: Requires a patch to support custom speeds that is not yet part of dc-load-ser 1.0.6. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 7b63f2d24c1b13cb65102b141293e594a87b1713 3161 3160 2023-07-06T17:34:06Z Tchan 166 corrected info about lik-sang cable wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** Disclaimer for Linux only: Requires a patch to support custom speeds that is not yet part of dc-load-ser 1.0.6. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 8dc60983cc6f2fac1ea002f885af2cff14dde488 3162 3161 2023-07-07T20:27:23Z Tchan 166 moved Linux disclaimer about custom speeds into the baudrate section wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') *** Disclaimer for Linux only: Requires a patch to support custom speeds that is not yet part of dc-load-ser 1.0.6. ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 568bb4e87993803f8f5efed0e2edd4ff8545ca51 3182 3162 2023-08-15T08:07:57Z Tchan 166 added link to Colton's PCB files wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] **** eg [https://github.com/cepawiel/dc-serial Colton's custom PCB] - Kicad files to order a custom PCB with a CP2102N, to be soldered to the serial connector of a DC SD Adapter V2 *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') *** Disclaimer for Linux only: Requires a patch to support custom speeds that is not yet part of dc-load-ser 1.0.6. ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} e8f419ae8d612ce6316cf6e4b9d4493132ac5f17 3187 3182 2023-09-10T13:51:27Z Tchan 166 adapted Linux & MacOS disclaimers with the latest info, after commit of Linux custom baudrates has been added to the repo wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == How to build/buy a cable == * Buy: ** eg [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. ** (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) * Build: ** DC serial connector: *** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} ** select a usb-to-serial chip/cable (+- 10 USD) *** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: **** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. **** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] **** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] **** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] **** eg [https://github.com/cepawiel/dc-serial Colton's custom PCB] - Kicad files to order a custom PCB with a CP2102N, to be soldered to the serial connector of a DC SD Adapter V2 *** FDTI's '''FT232R'''-like chips: **** '''good until 781250''', does not support 1562500. **** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. ***** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... ** connect the following pins (cfr [[Serial_interface]]): *** GND <-> GND *** TXD <-> RXD *** RXD <-> TXD *** RTS <-> CTS *** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') *** Disclaimer for Linux only: needs dc-tool-ser (host) changes from 4 september 2023 to select custom baudrates *** Disclaimer for MacOS only: custom baudrates are not supported yet ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} d5aa1e287ec0a921ca2c7f5c8c99a7e29ec12d1a Serial interface 0 93 3152 1707 2023-07-03T21:30:25Z Tchan 166 added link to Coder's_cable page wikitext text/x-wiki The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. [[File:Serial Pinout.png|thumb|PCB Serial Port with Labeled Pins]] {| class="wikitable" |+Serial connector pinout |- ! Pin ! Description |- |1 | +5V |- |2 |SCK |- |3 |Ground |- |4 |RX2 |- |5 |TX2 |- |6 |RTS |- |7 |CTS |- |8 |Ground |- |9 |Reset |- |10 | +3.3V |} [[File:Serial Pads.png|thumb|Serial Connection Pinout for Test Points on Bottom of Board]] A SCIF loopback connection can be created to allow a Dreamcast to conduct and pass the SCIF test on the official Sega [[DC Checker]] diagnostics software by connecting pin 4 (RX2) to pin 5 (TXD) and connecting pin 6 (RTS) to pin 7 (CTS). The serial interface is used by the [[Coder's_cable]] {{DCWiki:Stub}} a47d4e664e88206457c11649da86bbb2b5fdf526 3153 3152 2023-07-03T21:31:23Z Tchan 166 moved link to coder's cable to the top of the page wikitext text/x-wiki The Dreamcast has a serial interface on the back of the console used for several peripherals and for console debugging. The serial interface is used by the [[Coder's_cable]]. [[File:Serial Pinout.png|thumb|PCB Serial Port with Labeled Pins]] {| class="wikitable" |+Serial connector pinout |- ! Pin ! Description |- |1 | +5V |- |2 |SCK |- |3 |Ground |- |4 |RX2 |- |5 |TX2 |- |6 |RTS |- |7 |CTS |- |8 |Ground |- |9 |Reset |- |10 | +3.3V |} [[File:Serial Pads.png|thumb|Serial Connection Pinout for Test Points on Bottom of Board]] A SCIF loopback connection can be created to allow a Dreamcast to conduct and pass the SCIF test on the official Sega [[DC Checker]] diagnostics software by connecting pin 4 (RX2) to pin 5 (TXD) and connecting pin 6 (RTS) to pin 7 (CTS). {{DCWiki:Stub}} 3db125f46a6aef93faa27518e48a0c655b4d840d VMU emulators 0 118 3163 2087 2023-07-13T11:27:06Z GyroVorbis 13 /* ElysianVMU */ wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official Page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Core Source Code : [https://github.com/gyrovorbis/libevmu|GitHub] * Documentation : [http://vmu.elysianshadows.com/index.html http://vmu.elysianshadows.com/index.html] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= The original VMU emulator, written by the man who helped to reverse engineer the platform and kickstart the homebrew scene. * Official Page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android =Visual Memory Emulator= * Google Play : [https://play.google.com/store/apps/details?id=com.nuritsubushi.vmemu] * Developer : Kum * Compatibility : Unknown * Platform(s) : Android =DirectVMS= *Developer : [http://www.fallenrealm.com/directvms/index.html Fallen Realm] *Platforms: Windows * Latest release: 1.8, 09/24/2000 * Download [http://www.dcemulation.org/files/pcemu/DirectVMUexec.zip Binary], [http://www.dcemulation.org/files/pcemu/DirectVMUsource.zip Source Code] f6f785fa50e64e4f5ecd941052c2a56aa93ffacd 3164 3163 2023-07-13T11:27:27Z GyroVorbis 13 /* ElysianVMU */ wikitext text/x-wiki VMU Emulators are software applications that allow you to run enjoy VMU ROMs, games, applications, and animations without needing the actual VMU hardware. =ElysianVMU= ElysianVMU is a cross-platform feature-rich emulator being developed alongside the Elysian Shadows Toolkit, with the goal of bringing Dreamcast-exclusive VMU content to all platforms supported by their engine. The team has decided to release the emulator to the Dreamcast scene. It serves as a gaming platform, VMU filesystem manager, and even includes development tools targeted at helping developers write custom VMU software. * Official Page : [https://evmu.elysianshadows.com https://evmu.elysianshadows.com] * Core Source Code : [https://github.com/gyrovorbis/libevmu GitHub] * Documentation : [http://vmu.elysianshadows.com/index.html http://vmu.elysianshadows.com/index.html] * Developer by : [[User:GyroVorbis|Falco Girgis]], Elysian Shadows Team * Status : Active * Compatibility: Very Good * Platform(s) : ** Full Support: Windows, MacOS, Linux, Web, PSP, Raspberry Pi ** Partial Support: GameCube ** Future Support: iOS, Android, Dreamcast * Features ** Supported File Formats: *** ROM Images: .VMI/.VMS, .DCI, *** Flash Images: .DCM, .VMU *** Other: .BIN (bios), .LCD (VMU Animator) ** Emulation *** Save/Load State *** Japanese + US Bios Support *** Accurate Audio *** Gamepad/Joystick Support *** Analog Stick Support *** Fullscreen and Pixel-Perfect Scaling Modes *** Physically Accurate LCD Emulation (pixel ghosting, emulated grayscale) *** Fast-Forward *** Low-battery Emulation *** Serial Communications **** VMU-to-DC (using Maple over TCP/IP) ***** ESTk/Elysian Shadows Engine support (full) ***** DC Emulator support (WIP, pending someone willing to collaborate) **** VMU-to-VMU ***** TCP/IP (partial support, WIP) ***** Serial/GPIO pins (Raspberry Pi only, WIP) ** Filesystem Tools *** File Filesystem Manager *** VMU Animator File Playback *** VMU Icon Ripping *** VMU EyeCatch Ripping *** Framebuffer Screenshot Capture *** Record to Animated GIF *** Convert/Export between file formats *** Modify Volume Icon + Color *** Jet Set (Grind) Radio Custom Graffiti Tool (WIP) *** Lock/Unlock Extra Blocks *** Defragmenter *** File Checking/Repair/Debugging ** Developer Tools *** Frame-by-Frame Execution *** Real-Time Memory Browser and Hex Editor (RAM/Flash) *** Invalid Hardware Operation/Warning Log *** Buzzer Tool (for audio composition/debugging) (WIP) =SoftVMS= The original VMU emulator, written by the man who helped to reverse engineer the platform and kickstart the homebrew scene. * Official Page : [https://www.zophar.net/consoles/dreamcast/vms/softvms.html](https://www.zophar.net/consoles/dreamcast/vms/softvms.html) * Developer : Marcus Comstedt * Status : Inactive * Compatibility: Good * Platform(s) : Windows =VeMUlator PRO= * Google Play : [https://apkhome.net/vemulator-pro-dreamcast-vmu-emulator-0-7/] * Developer : MJaoune Software * Compatibility: Unknown * Platform(s) : Android =Visual Memory Emulator= * Google Play : [https://play.google.com/store/apps/details?id=com.nuritsubushi.vmemu] * Developer : Kum * Compatibility : Unknown * Platform(s) : Android =DirectVMS= *Developer : [http://www.fallenrealm.com/directvms/index.html Fallen Realm] *Platforms: Windows * Latest release: 1.8, 09/24/2000 * Download [http://www.dcemulation.org/files/pcemu/DirectVMUexec.zip Binary], [http://www.dcemulation.org/files/pcemu/DirectVMUsource.zip Source Code] 6d49875875108b16dbcb077775229701d3516dc2 VMU development 0 99 3165 3051 2023-07-15T03:03:51Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's Visual Memory Unit or "VMU" (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available and will be updated every time a new resource is found or new discovery is made. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site] or the [https://vmu.elysianshadows.com/hardware_docs.html ElysianVMU Hardware Docs]. A combination of these sites and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU serial connectivity]] Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://vmu.elysianshadows.com/hardware_docs.html ElysianVMU Hardware Docs] - Address spaces, instruction set architecture, undocumented SFRs, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 85a82df4bf2dd8e03fb6cfd658495222fca4cb2f 3174 3165 2023-07-28T11:53:10Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's Visual Memory Unit or "VMU" (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available and will be updated every time a new resource is found or new discovery is made. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site] or the [https://vmu.elysianshadows.com/hardware_docs.html ElysianVMU Hardware Docs]. A combination of these sites and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== Beginner's Tutorials ===== Candle-Electric, aka "Marble_Granite" has begun working on a series of beginner-focused tutorials which can be found on [https://github.com/Candle-Electric/VMU_Development_Beginners-Tutorial/ GitHub]. Unlike many of these resources, this set of tutorials is brand new, is using the latest recommended tools (LibPerspective, Waterbear, ElysianVMU). It walks you through the process from using the tools and assembling code to drawing to the framebuffer and getting input, with more tutorials on the way. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU serial connectivity]] Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://vmu.elysianshadows.com/hardware_docs.html ElysianVMU Hardware Docs] - Address spaces, instruction set architecture, undocumented SFRs, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual 5fc44687f8c030836306d552dc0b78462e558d36 3176 3174 2023-07-28T11:56:21Z GyroVorbis 13 wikitext text/x-wiki [[File:Multicolored VMUs.jpg|thumb|Various different faces of the VMU]] Developing standalone games for the Sega Dreamcast's Visual Memory Unit or "VMU" (also known as VMS) is both a challenging and rewarding development feat. On one hand, it's not the easiest embedded device to target, given that it doesn't have a C compiler and has its own set of hardware eccentricities. On the other hand, the device features a rich instruction set, 3 different clock sources, a FAT filesystem, and many different peripherals which can be leveraged by a developer, making it something of a Sega Saturn of little 8-bit gaming devices. While there is an active and ongoing effort within the scene to lower the barrier of entry into VMU development and to get more high-quality tutorials and materials out there for newbies, this page will hopefully serve as an entry point based on what is currently available and will be updated every time a new resource is found or new discovery is made. === Hardware === [[File:VMU Memory Map.png|thumb|VMU's multiple segmented and banked address spaces]] [[File:VMU System Block Diagram.png|thumb|VMU System Block Diagram]] A high-level overview of the VMU's technical specifications can be found [[VMU_hardware_overview|here]]. A good initial look at application-development for the device can be found [https://mc.pp.se/dc/vms/index.html at Marcus Comstedt's VMU Programming Site] or the [https://vmu.elysianshadows.com/hardware_docs.html ElysianVMU Hardware Docs]. A combination of these sites and the official [[:File:VMU.pdf|VMU Development Manual]] is typically what is referenced while programming for the VMU. Between the two, a developer should have all of the hardware documentation necessary to cover the following concepts: * Address Spaces, memory segments and banks * Opcodes and instructions * Addressing modes * System vs application execution * Built-in firmware routines * Special Function Registers (SFRs) * Interrupt service routines and their configuration * Controlling clock and oscillator circuits * Driving the LCD display by writing to XRAM * Reading/Writing to extra Working Memory (WRAM) * Controlling the Base Timer, and 2 Timer/Counter peripherals * Driving the piezoelectric Buzzer for sound output * Detecting button presses on Port 3 * Low-battery detection circuit and configuration * Serial communications via the 2 SIO interfaces === Programming === Since there is no C compiler for the VMU's 8-bit Sanyo CPU, development is traditionally done in Sanyo LC86k assembly language; however, it is now also possible to write C code indirectly targeting the device via emulation of the ARM Cortex M23 CPU. ==== C ==== Thanks to the uM23 emulator, it is now possible to indirectly write C code for the VMU. The code is cross-compiled for the ARM Cortex M23 target, and the resulting binary image is then loaded onto the VMU as a "DATA" file. The uM23 emulator, which must be loaded onto the device as the main "GAME" file, will then allow you to select an ARM binary image to run from its menu. More information can be found [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking here]. ==== LC86k Assembly Code ==== ===== waterbear ===== The [https://github.com/wtetzner/waterbear waterbear assembler/disassembler] is the favored tool for creating VMU binaries, as it is cross-platform, is feature-rich, supports all undocumented opcodes and SFRs, and is still under active development. * [https://github.com/wtetzner/waterbear/releases/latest Download the latest release] * [https://wtetzner.github.io/waterbear/ Documentation] ===== LibPerspective ===== Due to the non-contiguous, banked nature of XRAM, it is actually a nontrivial engineering feat to blit an image to the LCD screen. LibPerspective is a simple rendering library developed to aid in such tasks. It is frequently used in modern VMU homebrew and will enable you to work with rendering bitmaps to the display much more quickly. More information can be found [https://slum.online/dreamcast/ here]. A newer, maintained version of the LibPerspective codebase can be found [https://github.com/eatcomics/libperspective here], already featuring a couple bugfixes. ===== Beginner's Tutorials ===== [[File:VMU Dev Lesson 1.png|thumb|Screenshot from Marble_Grainite's first VMU Dev Lesson]] Candle-Electric, aka "Marble_Granite" has begun working on a series of beginner-focused tutorials which can be found on [https://github.com/Candle-Electric/VMU_Development_Beginners-Tutorial/ GitHub]. Unlike many of these resources, this set of tutorials is brand new, is using the latest recommended tools (LibPerspective, Waterbear, ElysianVMU). It walks you through the process from using the tools and assembling code to drawing to the framebuffer and getting input, with more tutorials on the way. ===== VMS Tetris ===== [[File:VMU Tetris Screenshot.gif|thumb|Marcus Comstedt's "VMU Tetris"]] The source code to Marcus Comstedt's VMU version of Tetris serves as a a great beginner resource, as it is well-commented and is a fairly complex game. The source code can be found [https://mc.pp.se/dc/files/tetris.s here]. ===== Audio Driver (ADVM) ===== jvsTSX has released an audio driver called ADVM open source on [https://github.com/jvsTSX/ADVM github]. This is some pretty advanced buzzer usage with well-written code including comments, most likely the deepest the homebrew scene has gone with this peripheral. Definitely something to be checked out for doing any sort of audio signal generation on the device. ===== Tiny3D Engine ===== [[File:Tiny 3D Engine.gif|thumb|Tiny3D Engine in Action]] Tiny3D Engine is a full-fledged 3D rendering engine, complete with OpenGL-style matrix stack, matrix/vector transformations, perspective matrix and division, line rendering and clipping, and 16-bit fixed point math routines. It was developed by The Rockin'-B and was originally released as a demo ROM featuring the engine with a menu that allowed for the configuration of the underlying 3D primitive and transformation matrix. The ROM and full source code can be found [https://github.com/gyrovorbis/tiny3dengine here]. ===== Scrolling Text Demo ===== The source to a scrolling text tech demo by VirtuaMUnstaz can be found here: [[File:Scrolling Text Tech Demo.zip]]. ===== Raining Squares ===== Raining Squares is a tech demo which serves as a great example for newbies to the platform. More information can be found [http://sebastianmihai.com/raining-squares.html here]. ===== Skeleton Application ===== The code for an example skeleton VMU application by Tyro can be found here: [[File:Skeleton VMU Application.zip]] ===== VMU Racketball ===== [[File:Racketball2.gif|thumb|VMU Racketball Screen Capture]] VMU Racketabll is an open-source VMU minigame developed by pxcla (Shirobon), which has been made available on [https://github.com/ppxxcc/VMU-Racketball github]. It contains fantastic comments and has been developed with the intention of serving as a kind of tutorial/learning tool for VMU developers as well. ===== Advent Wreath ===== Advent Wreath is a VMU application developed by Marble_Granite, that was released to commemorate the 24th anniversary of the Dreamcast and the 1st day of Advent. It demonstrates button input, impressive animations, and grayscale effects. Its source code can be found [https://github.com/Candle-Electric/Advent_Wreath here]. ===== Official Demos ===== An assortment of (older) tools and demos adapted from the official documentation has been compiled by frozenbinarystudio from the DCEmu forums and is available here: [[File:VMU Development Resources.gz]] ===== BIOS Disassembly ===== An ongoing effort to completely document the BIOS and firmware routines can be found [https://github.com/gyrovorbis/vmu-bios-disassembly here]. This is how many discoveries were made about features and behaviors which were intentionally left undocumented within the Developer Manual. ==== VMU Script ==== A long-lost and forgotten VMU-specific pseudo scripting language which was around at the time of the Dreamcast's commercial lifespan and was used in at least one shipping commercial game. Unfortunately the language and tools have been lost to time. These pages that were saved in the Wayback Machine appear to be the only bits of VMUScript left on the internet: * [https://web.archive.org/web/20160319105810/http://www.vmuscript.8m.com/ The VMUScript home page] * [https://web.archive.org/web/20080513153313/http://www.vmuscript.8m.com/logic.html Example game] * [https://web.archive.org/web/20080513153444/http://www.vmuscript.8m.com/command_reference.html Command Reference] * [https://web.archive.org/web/20080513152825/http://www.vmuscript.8m.com/download/siren.txt Example for how to play a sound] * [https://web.archive.org/web/20080513153008/http://www.vmuscript.8m.com/downloading.html Downloads page]. Unfortunately the download links don't work. * [https://web.archive.org/web/20080513152533/http://www.vmuscript.8m.com/concepts.html Concepts] ==== LIME ==== [[File:Dream Animator.jpg|thumb|192px|Dream Animator Tool for creating VMU Animations]] Another lost VMU-specific language. Again, there are some pages preserved in the Wayback Machine: * [https://web.archive.org/web/20000903022349/http://www.metronet.com/~ocon/lime/ Home page] ==== Dream Animator ==== While not technically code or a programming language, the VMU Animator tool allowed for the easy creation of VMU animations or movies. These animations could then be exported to a VMS GAME file which could then be played on the actual device. Many of these animations are circulating around today, and the [http://www.booyaka.com/ Booyaka] website was an entire community based around them. Unfortunately the tool is rather dated and may not run under modern Windows. It can be found here: [[File:VMU Animator.zip]]. ''Note that the ElysianVMU emulator can play the intermediate .LCD files but cannot create or modify them.'' ==== Amiga VMU Devkit ==== [[File:AmigaVMU.png|thumb|A sample screenshot of the Amiga VMU development kit.]] This was a complete development kit for the AmigaOS systems, it included well known development tools such as the Aslc86k assembler, SoftVMS emulator and LCDis the disassembler. It also includes tools suited to the Amiga's workflow, Such as AREXX scripts for auto-launching SoftVMS from Workbench when you have double clicked a VMS/VMI file, Amiga CD32 controller support for SoftVMS, Personal Paint Macros for creating VM graphics and icon data, a selection of icons to match in with the various makeovers that Workbench received. It can be found [https://vmudev.dcemulation.org/software.html#avmudk here]. ==== DC Anim ==== DC Anim is another tool that allows you to edit and create your own VMU animations, supporting the same file format used by Dream Animator. It is available both as a Windows XP [http://www.dcemulation.org/files/pcemu/DCAnim.zip binary] and as the [http://www.dcemulation.org/files/pcemu/dcanimcode.zip source code]. ==== BMOVIE ==== [[File:BMOVE_Promo.gif|192px|right|caption|BMOVIE Promo]]BMOVIE was an incredibly ambitious, technically impressive video encoder for the VMU, created by a homebrew VMU and Sega Saturn developer who went by "Rockin-B." It could create highly compressed animations for the device which could be exported then embedded into other applications. It supported extremely long animations, playback in reverse, and later on emulated grayscale effects via pixel ghosting. While it unfortunately seems as though the actual encoder tool, playback code, and documentation are lost to time, several tech demo videos still survive today as ROMs which prove it was more than just a myth. Rockin-B has since disappeared from the VMU and Saturn scenes without a trace, and any attempts to contact him have been in vain. What's left of his site can be found [http://www.rockin-b.de/vmu-b-movie.html here]. === Testing === ==== Emulators ==== [[File:ElysianVMU Flash Editor.jpg|thumb|ElysianVMU's Flash Editor and Filesystem Manager]] The favored emulator for VMU development and testing is the ElysianVMU emulator, as it is cross-platform, is ranked top for features and accuracy, and is still actively developed. The emulator also has an explicit goal of offering a debugging environment to facilitate development. Much of the debugger is still under active development; however, just features like the RAM and flash memory explorer widgets can be of great use during development. More information on EVMU as well as other VMU emulators can be found [[VMU Emulators#ElysianVMU|here]]. ==== Physical Device ==== Before publishing or distributing your game, it is highly recommended that you still test on physical hardware. There are various ways through which one can get a GAME file onto the actual device depending on your Dreamcast's configuration and peripherals. * [https://bswirl.kitsunet.org/vmutool/release/about/?lg=en&menu=on VMU Tool] (AKA Dream Explorer) * [https://github.com/DC-SWAT/DreamShell DreamShell] * Web Browser * Nexus Memory Card * KOS VMU Game Loader Example === Tips and Tricks === ==== Grayscale Graphics ==== Several VMU games emulate grayscale graphics by alternating a pixel between black and white, where the resulting shade of gray that is produced is a function of the alternation frequency. This is possible due to the physical hardware characteristics of the LCD screen, as a pixel is not instantaneously lit, but rather has a small "fade-in" period. The ElysianVMU emulator attempts to emulate this behavior with the "pixel ghosting" option. ==== Serial Communications ==== [[File:Dreamcast-VMUs-Hooked.jpg|thumb|VMU-to-VMU serial connectivity]] Serial communications are the indie holy grail of the VMU, representing one of its final frontiers which has been virtually completely unexplored. Even commercial releases very rarely utilized it. The official Sega documentation contains several examples for driving VMU-to-VMU serial communications, and we are in the process of creating our own documentation [[VMU_serial_communication|here]]. ==== Unconstrained Flash Access ==== While the BIOS-provided flash operations constrain reads and writes to within the boundaries of the GAME file, it is possible to write and read directly to and from flash using the STF and LDF undocumented VMU instructions (supported by Waterbear) respectively. These instructions are what the BIOS uses to implement the higher-level firmware calls. Several homebrew games and applications have leveraged these to access other files stored within the VMU. One example is Dmitry's uM23 emulator using LDF to read ARM binaries as separate "DATA" files on the same filesystem. ==== USB-Powered VMU Mod ==== If you're constantly finding yourself in need of replacement CR2032 batteries during development, consider doing the [https://www.instructables.com/USB-Powered-VMU-hack/ USB Powered VMU Hack] on a spare VMU. [[File:Aa vmu mod.png|thumb|AA Battery VMU Mod by Jeff Chen]] ==== AA Batter-Powered VMU Mod ==== Another fantastic modification you can do to save yourself CR2032 batteries is the modification to power the device with a pair of AA type batteries, thanks to Jeff Chen. More information can be found [https://www.printables.com/model/398492-sega-dreamcast-vmu-aaa-battery-pack here]. ==== Sublime Text Syntax Definition ==== A syntax Sublime Text syntax definition for the LC86k assembly flavor, including instructions and SFRs can be found [https://github.com/travispaul/lc86k-assembly-syntax here]. This makes Sublime Text a pretty decent development environment for working with VMU assembly. ==== PC to VMU ==== Testing your software on a physical VMU can be quite challenging, there have been a number of different attempts to achieve this. Currently most people place their .VMS on an SD card and load on the Dreamcast with the [[Serial_SD_card_adapter|Serial SD card adapter]] and a copy of Dreamshell. Before the SD card adapter however, developers used [[dcload-serial]] and [[Dcload-ip]] to test their software on real hardware. There was even some attempts to create a cable to link the VMU to the PC directly either by using a serial port or a parallel port, you can read more about this [[VMU2PC|here.]] ==== 6Mhz VMU ==== The VMU actually contains an incredibly fast 6Mhz CF oscillator circuit, which is only enabled when the VMU is plugged into the Dreamcast controller, supplying it with external 5v power. The purpose of this oscillator is to power the BIOS implementation of the Maple stack, which has to service requests from the Dreamcast to read/write flash, play tones, check input, and display images, all done in software. Recently, it has been discovered that this CF oscillator can be enabled even while the VMU is in standalone GAME mode by setting bit 4 of OCR to '1', with bit 0 reset to '0'. This will allow you to do substantially more with the VMU's CPU; however, it will destroy its battery life. Fortunately, we now have power supply mods which can power the VMU via sources such as USB or AA batteries, offsetting the additional power consumption. To date, no application has ever taken advantage of this clock; however, jvsTSX has constructed a demonstration of this in his [https://github.com/jvsTSX/VMU-MISC-CODE SPEEDTEST]. ==== Dual-Tone Buzzer Audio ==== Despite the fact that the hardware documentation claims that Timer 1 mode 1 is "typically" used for tone generation, and despite the fact that every known game/app for the VMU with buzzer output uses this method, new research has shown that Timer 1's mode 3 "variable length pulse generator" is actually capable of producing a much larger variety of more impressive sounding tones. Mode 3 allows you to configure two separate square waves, one with a larger period, and one with a smaller period, which are combined together for PWM output into the buzzer. This allows you to conceptually create a high and a low tone simultaneously with a single PWM output pin. A demonstration of this has been created by jvsTSX and can be found in his [https://github.com/jvsTSX/VMU-MISC-CODE SOUND3_TEST]. === Community === If you have any questions, want to share your work, would like to contribute in any way, or would like to hang out with a community of other people interested in VMU and Dreamcast development, try the following links: * [http://dcemulation.org/phpBB/ DCEmulation Forums] - One of the biggest, most prolific Dreamcast web forums, with a technical goldmine of information * [https://discord.gg/bpDZHT78PA Simulant Discord] - The main hangout spot for Dreamcast developers within the scene * [https://discord.gg/SX2txgr Elysian Shadows Discord] - The main hangout spot for developers of the VMU "subscene," including the authors of WaterBear, ElysianVMU, uM23, etc === References === * [https://mc.pp.se/dc/vms/index.html Marcus Comstedt's VMU Programming Site] - Architecture overview, instruction map, SFR references, etc * [https://vmu.elysianshadows.com/hardware_docs.html ElysianVMU Hardware Docs] - Address spaces, instruction set architecture, undocumented SFRs, etc * [https://dmitry.gr/?r=05.Projects&proj=25.%20VMU%20Hacking Dmitry.gr VMU hacking] - uM23 Emulator Homepage * [http://slum.online/dreamcast/ Slum Online development] - LibPerspective and other VMU content * [[VMU Emulators#ElysianVMU|ElysianVMU]] - Emulator, File Manager, Debugger * [https://pkgsrc.se/emulators/softvms SoftVMS] - Emulator * [https://github.com/wtetzner/waterbear Waterbear] - VMU Assembler, Disassembler, VMS tools * [https://pkgsrc.se/devel/aslc86k aslc86k] - Assembler * [https://pkgsrc.se/devel/lcdis lcdis] - Disassembler * [https://www.deco.franken.de/myfiles/myfiles.html VMU Development and Tools] - Largely outdated with many broken links, still useful as a reference * [https://vmudev.dcemulation.org/directory.html VMU Dev] - Archived VMU Development site with assorted old, but useful information * [[:File:VMU.pdf|VMU.pdf]] - Official Sega VMU Development Manual fbf60460ab8e5546bd714df8ed083c54953fd217 Getting Started with Dreamcast development 0 694 3166 3129 2023-07-23T16:59:52Z Darc 1 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.0.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. 00f53d5c728a8696626b337586c4c57400865302 3167 3166 2023-07-23T17:08:56Z Darc 1 /* Further reading */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.0.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 8cab4bd2beb0bebe3ec02e81d670bff7c875fc75 3178 3167 2023-07-30T02:54:27Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager * Alpine-based Linux distributions using the default apk package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git subversion ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.0.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 2dcd1ede1567c8dc846376446782b2339d3380a5 3179 3178 2023-07-30T04:04:14Z Darc 1 /* Alpine-based Linux */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager * Alpine-based Linux distributions using the default apk package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain You'll need to choose one of the following pre-made toolchain configurations. The '''testing''' version uses GCC 13.1.0 with Newlib 4.3.0, the '''stable''' version uses GCC 9.3.0 and Newlib 3.3.0, and the '''legacy''' version uses GCC 4.7.4 and Newlib 2.0.0. We suggest trying to use the ''testing'' or ''stable'' version. The latest version has more features, while the stable version has long been used by the community and is known to work well. Run one of the following commands to make your choice: '''(for GCC 13.1):''' mv config.mk.testing.sample config.mk '''(for GCC 9.3):''' mv config.mk.stable.sample config.mk '''(for GCC 4.7):''' mv config.mk.legacy.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 3d07e5592f396738c3e4215913d4f74dc9da1d4f 3180 3179 2023-08-03T20:41:29Z Darc 1 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager * Alpine-based Linux distributions using the default apk package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the `README.md` file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 917e09950d09417074ab87650aa7dd91c5371369 3181 3180 2023-08-03T20:42:26Z Darc 1 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Debian- and Ubuntu-based Linux distributions using the default apt package manager * Fedora-based Linux distributions using the default dnf package manager * Arch-based Linux distributions using the default pacman package manager * Alpine-based Linux distributions using the default apk package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] d8b0ade44f5a8c1cf1cc28d70b83118d4a89d694 3189 3181 2023-09-13T23:02:05Z Darc 1 /* Introduction */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a Windows-native approach, see [[DreamSDK]] instead * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Linux-based systems ** Debian- and Ubunt-based distributions using the default apt package manger ** Fedora-based distributions using the default dnf package manager ** Arch-based distributions using the default pacman package manager ** Alpine-based distributions using the default apk package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] c3bf24b3a7ac2d516f72599d23426f03a7ac0e6b 3190 3189 2023-09-13T23:02:19Z Darc 1 /* Introduction */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * Microsoft Windows 10 via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a Windows-native approach, see [[DreamSDK]] instead * macOS on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * Linux-based systems ** Debian- and Ubuntu-based distributions using the default apt package manger ** Fedora-based distributions using the default dnf package manager ** Arch-based distributions using the default pacman package manager ** Alpine-based distributions using the default apk package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] b2c13961579630b2b30633cd4e1f48daba1222a3 3191 3190 2023-09-13T23:03:38Z Darc 1 /* Introduction */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 6d3e40da2297bd6a7f9cbd970c9a7de8bc45a667 3192 3191 2023-09-13T23:04:51Z Darc 1 /* Terms */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler (with Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] f6ecb865a7c4744120c1e8262ddd64661b9fabc9 3193 3192 2023-09-17T15:18:02Z BBHoodsta 2 /* Configuring and compiling KOS and kos-ports */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a C/C++/Objective-C compiler (with Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 5d18432f83ea835da138438cf646519c55d2e6e8 File:Padus DiscJuggler v6.00.1400 FINAL.zip 6 1393 3168 2023-07-24T02:13:47Z Darc 1 Uploaded own work with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Padus DiscJuggler v6.00.1400 FINAL installer}} |date=2006-04-18 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 41d8f2b1358eac1adf33007c00ca5dd474bbfee8 File:Padus .CDI File Mounter v1.0.0.12.zip 6 1394 3169 2023-07-24T02:41:39Z Darc 1 Uploaded own work with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Padus .CDI File Mounter v1.0.0.12}} |date=2023-07-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} e621dad31f2b8eb2190fb9cd8e7b7cb18cf626b4 DiscJuggler 0 1395 3170 2023-07-24T03:16:22Z Darc 1 Created page with "'''Padus DiscJuggler''' is a professional CD/DVD recording software program. Its native '''.CDI''' image format is by far the most common format used to image self-booting Dreamcast CDs. The final version is DiscJuggler 6.00.1400, released on April 18, 2006, and it was sold up until around April 2011. DiscJuggler is compatible with Windows XP, Vista, 7, 8, 10, and 11. It also works very well with the Wine compatibility layer on Linux when the wineprefix is set to Window..." wikitext text/x-wiki '''Padus DiscJuggler''' is a professional CD/DVD recording software program. Its native '''.CDI''' image format is by far the most common format used to image self-booting Dreamcast CDs. The final version is DiscJuggler 6.00.1400, released on April 18, 2006, and it was sold up until around April 2011. DiscJuggler is compatible with Windows XP, Vista, 7, 8, 10, and 11. It also works very well with the Wine compatibility layer on Linux when the wineprefix is set to Windows XP 32-bit mode. Additionally, Padus provided a .CDI file mounting library which developers can use to integrate .CDI file handling in their Windows programs. This can be used as a plugin for the [https://www.imgburn.com/ ImgBurn] software to allow burning DiscJuggler .CDI files. ImgBurn is only available for Windows, but like DiscJuggler, it works very well with the Wine compatibility layer on Linux, just make sure to use a Windows XP wineprefix. You may also need to set the I/O Interface option in Settings to "SPTI - Microsoft" for optical drives to be detected properly while using Wine. * [[:File:Padus_DiscJuggler_v6.00.1400_FINAL.zip|Download DiscJuggler v6.00.1400]] * [[:File:Padus_.CDI_File_Mounter_v1.0.0.12.zip|Download Padus .CDI File Mounting Library]], aka CDI plugin for ImgBurn ==Burning CDI files using DiscJuggler== ==Burning CDI files using ImgBurn== ==Burning CDI files using cdirip and Burn on a Mac== ==Burning CDI files using cdirip and cdrecord== 84d32270bf54e567c9b0ac4225512a38d8ee8319 3171 3170 2023-07-24T03:34:52Z Darc 1 wikitext text/x-wiki '''Padus DiscJuggler''' is a professional CD/DVD recording software program. Its native '''.CDI''' image format is by far the most common format used to image self-booting Dreamcast CDs. The final version is DiscJuggler 6.00.1400, released on April 18, 2006, and it was sold up until around April 2011. DiscJuggler is compatible with Windows XP, Vista, 7, 8, 10, and 11. It also works very well with the Wine compatibility layer on Linux when the wineprefix is set to Windows XP 32-bit mode. Additionally, Padus provided a .CDI file mounting library which developers can use to integrate .CDI file handling in their Windows programs. This can be used as a plugin for the [https://www.imgburn.com/ ImgBurn] software to allow burning DiscJuggler .CDI files. ImgBurn is only available for Windows, but like DiscJuggler, it works very well with the Wine compatibility layer on Linux, just make sure to use a Windows XP wineprefix. You may also need to set the I/O Interface option in Settings to "SPTI - Microsoft" for optical drives to be detected properly while using Wine. * [[:File:Padus_DiscJuggler_v6.00.1400_FINAL.zip|Download DiscJuggler v6.00.1400]] * [[:File:Padus_.CDI_File_Mounter_v1.0.0.12.zip|Download Padus .CDI File Mounting Library]], aka CDI plugin for ImgBurn * [https://github.com/sizious/cdi2nero cdi2nero] -- Convert CDI files to Nero .NRG format * [https://github.com/jozip/cdirip cdirip] -- For advanced users: rip CDI files into individual tracks for manual burning ==Dreamcast image standard== Because the Dreamcast [[MIL-CD]] self-bootable disc format requires multiple sessions be recorded to disc, a Dreamcast CD cannot be represented using an ISO file, which only represents a single CD data track. The most common format in the early 2000s for game discs was CDRWIN's bin/cue format, but while this format supports multiple tracks, it does not support multiple sessions without 3rd party extensions that didn't come until much later. Therefore, when the first Dreamcast CD images began to be distributed, the DiscJuggler image format was chosen and soon became the timeless standard for Dreamcast discs. Later, [[Nero]] '''.NRG''' and [[Alcohol 120%]] '''.MDF/.MDS''' files were used as secondary standard formats by some users. ==Burning CDI files using DiscJuggler== ==Burning CDI files using ImgBurn== ==Burning CDI files using cdirip and Burn on a Mac== ==Burning CDI files using cdirip and cdrecord== 2edc97b13f931d6a835969497bf787adae734b0b 3172 3171 2023-07-24T04:07:18Z Darc 1 wikitext text/x-wiki '''Padus DiscJuggler''' is a professional CD/DVD recording software program. Its native '''.CDI''' image format is by far the most common format used to image self-booting Dreamcast CDs. The final version is DiscJuggler 6.00.1400, released on April 18, 2006, and it was sold up until around April 2011. DiscJuggler is compatible with Windows XP, Vista, 7, 8, 10, and 11. It also works very well with the Wine compatibility layer on Linux when the wineprefix is set to Windows XP 32-bit mode. Additionally, Padus provided a .CDI file mounting library which developers can use to integrate .CDI file handling in their Windows programs. This can be used as a plugin for the [https://www.imgburn.com/ ImgBurn] software to allow burning DiscJuggler .CDI files. ImgBurn is only available for Windows, but like DiscJuggler, it works very well with the Wine compatibility layer on Linux, just make sure to use a Windows XP wineprefix. You may also need to set the I/O Interface option in Settings to "SPTI - Microsoft" for optical drives to be detected properly while using Wine. * [[:File:Padus_DiscJuggler_v6.00.1400_FINAL.zip|Download DiscJuggler v6.00.1400]] * [[:File:Padus_.CDI_File_Mounter_v1.0.0.12.zip|Download Padus .CDI File Mounting Library]], aka CDI plugin for ImgBurn * [https://github.com/sizious/cdi2nero cdi2nero] -- Convert CDI files to Nero .NRG format * [https://github.com/jozip/cdirip cdirip] -- For advanced users: rip CDI files into individual tracks for manual burning ==Dreamcast image standard== Because the Dreamcast [[MIL-CD]] self-bootable disc format requires multiple sessions be recorded to disc, a Dreamcast CD cannot be represented using an ISO file, which only represents a single CD data track. The most common format in the early 2000s for game discs was CDRWIN's bin/cue format, but while this format supports multiple tracks, it does not support multiple sessions without 3rd party extensions that didn't come until much later. Therefore, when the first Dreamcast CD images began to be distributed, the DiscJuggler image format was chosen and soon became the timeless standard for Dreamcast discs. Later, [[Nero]] '''.NRG''' and [[Alcohol 120%]] '''.MDF/.MDS''' files were used as secondary standard formats by some users. ==Burning CDI files using DiscJuggler== * Install DiscJuggler using the above installer, following the directions in the readme.txt file. * Open DiscJuggler and click File > New. * Select "Burn disc images". * Select the .CDI file you wish to burn using the "Source" box. * Select the CD burner you wish to use using the "Destination" box. * Select Action > Write. * Select your desired burn speed under Method. Some users find slower burn speeds to produce more reliable discs. * Despite popular belief, '''it is unnecessary to set any settings under the Advanced tab.''' The .CDI file contains all the information DiscJuggler needs to know. Just leave it alone. * Click Start to burn disc. ==Burning CDI files using ImgBurn== ''ImgBurn is usually very reliable with burning DiscJuggler CDI files, but on rare occasions there may be incompatible discs requiring the use of the original DiscJuggler software.'' * Install ImgBurn. Download the ''Padus .CDI File Mounting Library, aka CDI plugin for ImgBurn'' file above. Extract its contents to the ImgBurn folder in Program Files. * Open ImgBurn. Select "Write image file to disc". * Select the .CDI file you wish to burn as the Source. * Select the CD burner you wish to use using the "Destination" setting. * Select your desired burn speed under Settings. Some users find slower burn speeds to produce more reliable discs. * Click the burn button to begin. ==Burning CDI files using cdirip and Burn on a Mac== * '''TODO''' ** Rip CDI file using ''cdirip image.cdi -bin'' ** Burn first session cuesheet with '''Allow more sessions''' checked, burn second session cuesheet with it unchecked ==Burning CDI files using cdirip and cdrecord== * '''TODO''' ** Rip CDI file using ''cdirip image.cdi'' ** Burn using cdrecord or cdrkit afba1fd9895e66e6d17395f2d8e85cdde07a6038 3173 3172 2023-07-24T04:09:43Z Darc 1 wikitext text/x-wiki '''Padus DiscJuggler''' is a professional CD/DVD recording software program. Its native '''.CDI''' image format is by far the most common format used to image self-booting Dreamcast CDs. The final version is DiscJuggler 6.00.1400, released on April 18, 2006, and it was sold up until around April 2011. DiscJuggler is compatible with Windows XP, Vista, 7, 8, 10, and 11. It also works very well with the Wine compatibility layer on Linux when the wineprefix is set to Windows XP 32-bit mode. Additionally, Padus provided a .CDI file mounting library which developers can use to integrate .CDI file handling in their Windows programs. This can be used as a plugin for the [https://www.imgburn.com/ ImgBurn] software to allow burning DiscJuggler .CDI files. ImgBurn is only available for Windows, but like DiscJuggler, it works very well with the Wine compatibility layer on Linux, just make sure to use a Windows XP wineprefix. You may also need to set the I/O Interface option in Settings to "SPTI - Microsoft" for optical drives to be detected properly while using Wine. * [[:File:Padus_DiscJuggler_v6.00.1400_FINAL.zip|Download DiscJuggler v6.00.1400]] -- complete final version * [[:File:Padus_.CDI_File_Mounter_v1.0.0.12.zip|Download Padus .CDI File Mounting Library]], aka CDI plugin for ImgBurn * [https://github.com/sizious/cdi2nero cdi2nero] -- Convert CDI files to Nero .NRG format * [https://github.com/jozip/cdirip cdirip] -- For advanced users: rip CDI files into individual tracks for manual burning ==Dreamcast image standard== Because the Dreamcast [[MIL-CD]] self-bootable disc format requires multiple sessions be recorded to disc, a Dreamcast CD cannot be represented using an ISO file, which only represents a single CD data track. The most common format in the early 2000s for game discs was CDRWIN's bin/cue format, but while this format supports multiple tracks, it does not support multiple sessions without 3rd party extensions that didn't come until much later. Therefore, when the first Dreamcast CD images began to be distributed, the DiscJuggler image format was chosen and soon became the timeless standard for Dreamcast discs. Later, [[Nero]] '''.NRG''' and [[Alcohol 120%]] '''.MDF/.MDS''' files were used as secondary standard formats by some users. ==Burning CDI files using DiscJuggler== * Install DiscJuggler using the above installer, following the directions in the readme.txt file. * Open DiscJuggler and click File > New. * Select "Burn disc images". * Select the .CDI file you wish to burn using the "Source" box. * Select the CD burner you wish to use using the "Destination" box. * Select Action > Write. * Select your desired burn speed under Method. Some users find slower burn speeds to produce more reliable discs. * Despite popular belief, '''it is unnecessary to set any settings under the Advanced tab.''' The .CDI file contains all the information DiscJuggler needs to know. Just leave it alone. * Click Start to burn disc. ==Burning CDI files using ImgBurn== ''ImgBurn is usually very reliable with burning DiscJuggler CDI files, but on rare occasions there may be incompatible discs requiring the use of the original DiscJuggler software.'' * Install ImgBurn. Download the ''Padus .CDI File Mounting Library, aka CDI plugin for ImgBurn'' file above. Extract its contents to the ImgBurn folder in Program Files. * Open ImgBurn. Select "Write image file to disc". * Select the .CDI file you wish to burn as the Source. * Select the CD burner you wish to use using the "Destination" setting. * Select your desired burn speed under Settings. Some users find slower burn speeds to produce more reliable discs. * Click the burn button to begin. ==Burning CDI files using cdirip and Burn on a Mac== * '''TODO''' ** Rip CDI file using ''cdirip image.cdi -bin'' ** Burn first session cuesheet with '''Allow more sessions''' checked, burn second session cuesheet with it unchecked ==Burning CDI files using cdirip and cdrecord== * '''TODO''' ** Rip CDI file using ''cdirip image.cdi'' ** Burn using cdrecord or cdrkit d6df3ef5c093610d552eb9b13c5137e96ccd5982 3177 3173 2023-07-28T22:04:59Z Darc 1 wikitext text/x-wiki '''Padus DiscJuggler''' is a professional CD/DVD recording software program. Its native '''.CDI''' image format is by far the most common format used to image self-booting Dreamcast CDs. The final version is DiscJuggler 6.00.1400, released on April 18, 2006, and it was sold up until around April 2011. DiscJuggler is compatible with Windows XP, Vista, 7, 8, 10, and 11. It also works very well with the Wine compatibility layer on Linux when the wineprefix is set to Windows XP 32-bit mode. Additionally, Padus provided a .CDI file mounting library which developers can use to integrate .CDI file handling in their Windows programs. This can be used as a plugin for the [https://www.imgburn.com/ ImgBurn] software to allow burning DiscJuggler .CDI files. ImgBurn is only available for Windows, but like DiscJuggler, it works very well with the Wine compatibility layer on Linux, just make sure to use a Windows XP wineprefix, and once installed, enter the Settings menu and set the I/O Interface option to "SPTI - Microsoft" and the "SPTI - Device Enumeration Method" to "Device Interface" for optical drives to be detected properly while using Wine. * [[:File:Padus_DiscJuggler_v6.00.1400_FINAL.zip|Download DiscJuggler v6.00.1400]] -- complete final version * [[:File:Padus_.CDI_File_Mounter_v1.0.0.12.zip|Download Padus .CDI File Mounting Library]], aka CDI plugin for ImgBurn * [https://github.com/sizious/cdi2nero cdi2nero] -- Convert CDI files to Nero .NRG format * [https://github.com/jozip/cdirip cdirip] -- For advanced users: rip CDI files into individual tracks for manual burning ==Dreamcast image standard== Because the Dreamcast [[MIL-CD]] self-bootable disc format requires multiple sessions be recorded to disc, a Dreamcast CD cannot be represented using an ISO file, which only represents a single CD data track. The most common format in the early 2000s for game discs was CDRWIN's bin/cue format, but while this format supports multiple tracks, it does not support multiple sessions without 3rd party extensions that didn't come until much later. Therefore, when the first Dreamcast CD images began to be distributed, the DiscJuggler image format was chosen and soon became the timeless standard for Dreamcast discs. Later, [[Nero]] '''.NRG''' and [[Alcohol 120%]] '''.MDF/.MDS''' files were used as secondary standard formats by some users. ==Burning CDI files using DiscJuggler== * Install DiscJuggler using the above installer, following the directions in the readme.txt file. * Open DiscJuggler and click File > New. * Select "Burn disc images". * Select the .CDI file you wish to burn using the "Source" box. * Select the CD burner you wish to use using the "Destination" box. * Select Action > Write. * Select your desired burn speed under Method. Some users find slower burn speeds to produce more reliable discs. * Despite popular belief, '''it is unnecessary to set any settings under the Advanced tab.''' The .CDI file contains all the information DiscJuggler needs to know. Just leave it alone. * Click Start to burn disc. ==Burning CDI files using ImgBurn== ''ImgBurn is usually very reliable with burning DiscJuggler CDI files, but on rare occasions there may be incompatible discs requiring the use of the original DiscJuggler software.'' * Install ImgBurn. Download the ''Padus .CDI File Mounting Library, aka CDI plugin for ImgBurn'' file above. Extract its contents to the ImgBurn folder in Program Files. * Open ImgBurn. Select "Write image file to disc". * Select the .CDI file you wish to burn as the Source. * Select the CD burner you wish to use using the "Destination" setting. * Select your desired burn speed under Settings. Some users find slower burn speeds to produce more reliable discs. * Click the burn button to begin. ==Burning CDI files using cdirip and Burn on a Mac== * '''TODO''' ** Rip CDI file using ''cdirip image.cdi -bin'' ** Burn first session cuesheet with '''Allow more sessions''' checked, burn second session cuesheet with it unchecked ==Burning CDI files using cdirip and cdrecord== * '''TODO''' ** Rip CDI file using ''cdirip image.cdi'' ** Burn using cdrecord or cdrkit f3e7717b226e8805453cdb11e112f620cb15b4c0 File:VMU Dev Lesson 1.png 6 1396 3175 2023-07-28T11:55:04Z GyroVorbis 13 wikitext text/x-wiki Screenshot from Marble_Grainite's first VMU Dev Lesson d4795c1e77c0644787df963ae44bd32bf0ab3945 SH4 in Compiler Explorer 0 733 3183 3056 2023-08-21T04:52:52Z GyroVorbis 13 Updated with GCC13.2.0 templates wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: Compile code for the processor in little-endian mode * <code>-m4-single-only</code>: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: Breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/6Pdos6z7n C2X Hello World] ** [https://godbolt.org/z/71c9T3Yc4 C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 54c2e715d55ddab0aa60810fc5bf26819258205f 3196 3183 2023-09-20T03:12:31Z GyroVorbis 13 wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: Compile code for the processor in little-endian mode * <code>-m4-single-only</code>: Generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: Breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/rafvMdWGb C2X Hello World] ** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. dd18f934cf668c4750f0a8d53e6a8d823d2d3f76 3197 3196 2023-09-20T03:15:48Z GyroVorbis 13 /* Configuration */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: compile code for the processor in little-endian mode * <code>-m4-single-only</code>: generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). * <code>-matomic-model=soft-imask</code>: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations * <code>-ftls-model=local-exec</code>: enables the model supported by KOS for implementing variables declared with the "thread_local" keyword = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/rafvMdWGb C2X Hello World] ** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 3c02c463c5a80510e3bee0aa9c41d3b7b6fb6472 3198 3197 2023-09-20T03:16:35Z GyroVorbis 13 /* Configuration */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: compile code for the processor in little-endian mode * <code>-m4-single-only</code>: generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). * <code>-matomic-model=soft-imask</code>: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations * <code>-ftls-model=local-exec</code>: enables the model used by KOS for supporting variables declared with the "thread_local" keyword = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/rafvMdWGb C2X Hello World] ** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 282e48f179a2e719aa42805b37460fc54e922c23 32MB RAM expansion 0 284 3184 1843 2023-08-30T14:33:25Z Darc 1 /* Incompatibility issues */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issues are 1. Sofdec video playback in commercial games and 2. Windows CE. Games using Sofdec video will fail to play FMV, crashing and rebooting the console as a result. Windows CE games will not boot and either hang or reboot the system. More research is needed to determine if these issues can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> KallistiOS also includes [https://github.com/KallistiOS/KallistiOS/tree/master/examples/dreamcast/basic/memtest32 memtest32] in its example programs. Adapted from tsowell's original utility, memtest32 supports memory testing 16MB and 32MB Dreamcasts. ===DreamShell=== The latest version of the [[DreamShell]] operating system, which uses KallistiOS as its kernel, now supports 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X ==Emulators== ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when run with the <code>--ram-size=32</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir meson compile -C builddir ./builddir/lxdream-nitro --ram-size=32 035893b010db5b13779ffe92e43b098925ac9e82 Development 0 2 3185 3072 2023-09-06T14:10:30Z BBHoodsta 2 /* General */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Romdisk Swapping]] * [[Store Queues]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] 7c2cf206f42d8ea6d7e28715b0105f76c557f64a 3186 3185 2023-09-06T14:10:41Z BBHoodsta 2 /* General */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Store Queues]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] 83146eec0e87322204dc5a6f9bb93c865ba16b44 DreamSDK 0 1397 3188 2023-09-13T23:00:45Z Darc 1 Created page with "DreamSDK is a suite of Windows-based utilities for installing and managing a KallistiOS-based Dreamcast development environment. It was created and is maintained by [[SiZiOUS]]. * [https://www.dreamsdk.org/ DreamSDK website]" wikitext text/x-wiki DreamSDK is a suite of Windows-based utilities for installing and managing a KallistiOS-based Dreamcast development environment. It was created and is maintained by [[SiZiOUS]]. * [https://www.dreamsdk.org/ DreamSDK website] 39684661768ffb63b930afb3c9d7d606c907f026 Building KOS on MinGW-w64/MSYS2 0 991 3194 2173 2023-09-19T18:39:20Z BBHoodsta 2 /* Toolchain (cross-compiler and libraries) */ wikitext text/x-wiki ==Overview== This tutorial is a step-by-step guide on how to setup a toolchain and KOS environment on your Windows system. The toolchain consists of a C/C++ compiler (GCC), assembler and linker (binutils), and C library (newlib). As the Dreamcast has two processors - the SH4 CPU and the AICA (ARM) sound processor - the toolchain includes compilers for both. KOS consists of the operating system core (kos) and a set of nicely integrated libraries (kos-ports). Since KOS was developed for Unix-compatible systems (like Linux, BSD, etc.), a Unix-compatible development environment must be installed. The available choices are Cygwin, MSYS and MSYS2. MSYS is unmaintained and out-dated. Cygwin and MSYS2 both work, but MSYS2 seems to be maintained more actively, work better and also offers a better package management system, so it is preferred. ==Preparations== Install MSYS2 from http://repo.msys2.org/distrib/i686 (this tutorial used http://repo.msys2.org/distrib/i686/msys2-i686-20160205.exe). ''Please make sure to use partition C:\''. A user reported issues of git, wget, etc. not working at all when installing to partition D:\. On the MSys2 website it's mentioned that FAT filesystems don't work, so that's an alternative explanation. As the setup completes, it will ask whether you want to open a shell. Don't. Open ''C:\msys32\mingw32_shell.bat'' instead (mingw shell instead of msys2 shell). ==Install script== At this point, please consider trying the install script first. It will perform the remaining steps below automatically. Download the install script: [[File:Kos_setup_script.zip]]. Then change to the directory of the script and execute it (uses Unix paths instead of Windows paths, ''C:\'' becomes ''/c/'') $ cd /c/Documents\ and\ Settings (''find your Download folder here..'') $ sh kos_setup.sh The script should perform all the remaining steps. If something goes wrong, you can try to continue the steps manually or ask for help on the forums/IRC. ==Install required packages== MSYS2 uses the ''pacman'' package manager. The following command should download all required programs. $ pacman -Sy --needed mingw-w64-i686-binutils mingw-w64-i686-gcc mingw-w64-i686-pkg-config mingw-w64-i686-libpng mingw-w64-i686-libjpeg-turbo diffutils git make subversion patch python tar texinfo wget ==Downloading KOS== KOS is available through a Git repository at SourceForge. The standard install directory assumed in the configuration files is /opt/toolchains/dc/{kos, kos-ports}. $ git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ==Toolchain (cross-compiler and libraries)== After cloning the KOS repository, run the toolchain download+unpack+compile scripts: $ cd /opt/toolchains/dc/kos/utils/dc-chain Then compile the cross-compiler and system libraries. The erase=1 will delete temporary files after a successful build. $ make erase=1 After this command completes successfully you have a working cross-compiler for Dreamcast and can compile KOS next. ==Setting up KOS== You should read the documentation in the kos/doc directory for details, but here are the basic steps required to set up the KOS environment: Go into the kos directory and copy the template configuration: $ cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Now edit environ.sh to match your installation. If you use the default installation directory you don't need to change anything. Execute the following command to set the KOS environment variables: $ source /opt/toolchains/dc/kos/environ.sh Remember to do this every time you want to use the KOS environment in a newly opened shell. Dont't forget to run the above command again when editing environ.sh. Now we are finally ready to compile KOS itself. In the kos directory, run: $ cd /opt/toolchains/dc/kos $ make ==KOS-Ports== KOS-Ports is a repository with commonly used libraries for development on the DC, like PNG or MP3 loading. Clone the repository: $ git clone git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Compile all KOS-ports using the build-all script $ sh /opt/toolchains/dc/kos-ports/utils/build-all.sh Now you should have a working Dreamcast development environment :-) Check out the examples in the KallistiOS directory to find out how to use KOS in your own projects! 1934761481ca8d5dd196acb1063fdc8172581b01 3195 3194 2023-09-19T18:41:05Z BBHoodsta 2 /* Toolchain (cross-compiler and libraries) */ wikitext text/x-wiki ==Overview== This tutorial is a step-by-step guide on how to setup a toolchain and KOS environment on your Windows system. The toolchain consists of a C/C++ compiler (GCC), assembler and linker (binutils), and C library (newlib). As the Dreamcast has two processors - the SH4 CPU and the AICA (ARM) sound processor - the toolchain includes compilers for both. KOS consists of the operating system core (kos) and a set of nicely integrated libraries (kos-ports). Since KOS was developed for Unix-compatible systems (like Linux, BSD, etc.), a Unix-compatible development environment must be installed. The available choices are Cygwin, MSYS and MSYS2. MSYS is unmaintained and out-dated. Cygwin and MSYS2 both work, but MSYS2 seems to be maintained more actively, work better and also offers a better package management system, so it is preferred. ==Preparations== Install MSYS2 from http://repo.msys2.org/distrib/i686 (this tutorial used http://repo.msys2.org/distrib/i686/msys2-i686-20160205.exe). ''Please make sure to use partition C:\''. A user reported issues of git, wget, etc. not working at all when installing to partition D:\. On the MSys2 website it's mentioned that FAT filesystems don't work, so that's an alternative explanation. As the setup completes, it will ask whether you want to open a shell. Don't. Open ''C:\msys32\mingw32_shell.bat'' instead (mingw shell instead of msys2 shell). ==Install script== At this point, please consider trying the install script first. It will perform the remaining steps below automatically. Download the install script: [[File:Kos_setup_script.zip]]. Then change to the directory of the script and execute it (uses Unix paths instead of Windows paths, ''C:\'' becomes ''/c/'') $ cd /c/Documents\ and\ Settings (''find your Download folder here..'') $ sh kos_setup.sh The script should perform all the remaining steps. If something goes wrong, you can try to continue the steps manually or ask for help on the forums/IRC. ==Install required packages== MSYS2 uses the ''pacman'' package manager. The following command should download all required programs. $ pacman -Sy --needed mingw-w64-i686-binutils mingw-w64-i686-gcc mingw-w64-i686-pkg-config mingw-w64-i686-libpng mingw-w64-i686-libjpeg-turbo diffutils git make subversion patch python tar texinfo wget ==Downloading KOS== KOS is available through a Git repository at SourceForge. The standard install directory assumed in the configuration files is /opt/toolchains/dc/{kos, kos-ports}. $ git clone git://git.code.sf.net/p/cadcdev/kallistios /opt/toolchains/dc/kos ==Toolchain (cross-compiler and libraries)== After cloning the KOS repository, navigate to dc-chain directory: $ cd /opt/toolchains/dc/kos/utils/dc-chain Then compile the cross-compiler and system libraries. The erase=1 will delete temporary files after a successful build. $ make erase=1 After this command completes successfully you have a working cross-compiler for Dreamcast and can compile KOS next. ==Setting up KOS== You should read the documentation in the kos/doc directory for details, but here are the basic steps required to set up the KOS environment: Go into the kos directory and copy the template configuration: $ cp /opt/toolchains/dc/kos/doc/environ.sh.sample /opt/toolchains/dc/kos/environ.sh Now edit environ.sh to match your installation. If you use the default installation directory you don't need to change anything. Execute the following command to set the KOS environment variables: $ source /opt/toolchains/dc/kos/environ.sh Remember to do this every time you want to use the KOS environment in a newly opened shell. Dont't forget to run the above command again when editing environ.sh. Now we are finally ready to compile KOS itself. In the kos directory, run: $ cd /opt/toolchains/dc/kos $ make ==KOS-Ports== KOS-Ports is a repository with commonly used libraries for development on the DC, like PNG or MP3 loading. Clone the repository: $ git clone git://git.code.sf.net/p/cadcdev/kos-ports /opt/toolchains/dc/kos-ports Compile all KOS-ports using the build-all script $ sh /opt/toolchains/dc/kos-ports/utils/build-all.sh Now you should have a working Dreamcast development environment :-) Check out the examples in the KallistiOS directory to find out how to use KOS in your own projects! f68043d4322dc2a824e9fe2906df2c9cbfe97762 Redump2CDI 0 1398 3199 2023-09-23T21:52:49Z Darc 1 Created page with "'''Redump2CDI''' is a utility created by [[darc]] to convert Redump Dreamcast CD-ROM images to [[DiscJuggler]] format. The Redump image format is a non-standard form of BIN+CUE image that cannot be burned or mounted with current software, so conversion is convenient for non-archival purposes. Redump2CDI is intended only for Redump Dreamcast CD-ROM images. It is not intended to convert GD-ROM images or old schoool non-selfboot BIN+CUE Dreamcast files." wikitext text/x-wiki '''Redump2CDI''' is a utility created by [[darc]] to convert Redump Dreamcast CD-ROM images to [[DiscJuggler]] format. The Redump image format is a non-standard form of BIN+CUE image that cannot be burned or mounted with current software, so conversion is convenient for non-archival purposes. Redump2CDI is intended only for Redump Dreamcast CD-ROM images. It is not intended to convert GD-ROM images or old schoool non-selfboot BIN+CUE Dreamcast files. a8f71d310c7c1c22249774072f3d386180309feb Getting Started with Dreamcast development 0 694 3200 3193 2023-09-23T22:08:33Z Darc 1 /* Terms */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 23f9843431c84e8bc304a52a55ae8a3de0bd187b 3222 3200 2023-10-16T00:48:50Z Einsteinx2 6 Explicitly called out macOS requiring -j1 to build GCC toolchain wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ''Important Note for macOS users'': GCC will fail to build if you try to set a high <code>-j</code> value on macOS, but will build fine with <code>-j1</code>. Slightly higher values like <code>-j2</code> may also work, but that has not been confirmed. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 6e6ebd41516dd12d40c9ca5bbdf7b37fa90aed6e 3223 3222 2023-10-18T17:01:39Z Darc 1 Reverted edits by [[Special:Contributions/Einsteinx2|Einsteinx2]] ([[User talk:Einsteinx2|talk]]) to last revision by [[User:Darc|Darc]] wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makeopts=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 23f9843431c84e8bc304a52a55ae8a3de0bd187b 3224 3223 2023-11-06T18:32:16Z Darc 1 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makeopts</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 911a46cb7099f2cc05b133f5da4aeddd8429cdb2 3225 3224 2023-11-06T18:33:25Z Darc 1 /* Configuring the dc-chain script */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with the following command: dc-tool-ip -t <dreamcast IP address> -x example.elf Run <code>dc-tool-ip</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 8a432c25d106036f3179a2d9069d41b3f4422046 3234 3225 2023-11-27T23:04:22Z Darc 1 /* Running an example program through a debug link */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || Varies on used markets, uncommonly sold<br />RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 0ba8e0fb712114709afc55b3dd5b85b0a506a013 3235 3234 2023-11-29T00:02:23Z Darc 1 /* Choosing a debug link solution */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 68249b2a8063a976eca9d8fe543ed2af91886ae4 Redump2CDI 0 1398 3201 3199 2023-09-23T23:07:02Z Darc 1 wikitext text/x-wiki '''Redump2CDI''' is a utility created by [[darc]] to convert Redump Dreamcast CD-ROM images to [[DiscJuggler]] format. The Redump image format is a non-standard form of BIN+CUE image that cannot be burned or mounted with much existing software, so conversion is convenient for non-archival purposes. Redump2CDI is intended only for Redump Dreamcast CD-ROM images. It is not intended to convert GD-ROM images or old schoool non-selfboot BIN+CUE Dreamcast files. 683e49924a9d1ad9bc82ed2c9abac3a29190a32a 3203 3201 2023-09-23T23:12:52Z Darc 1 wikitext text/x-wiki '''Redump2CDI''' is a utility created by [[darc]] to convert Redump Dreamcast CD-ROM images to [[DiscJuggler]] format. The Redump image format is a non-standard form of BIN+CUE image that cannot be burned or mounted with much existing software, so conversion is convenient for non-archival purposes. Redump2CDI is intended only for Redump Dreamcast CD-ROM images. It is not intended to convert GD-ROM images or old schoool non-selfboot BIN+CUE Dreamcast files. * Download: [[:File:Redump2cdi-0.1.0-2023-09-23.zip|Redump2CDI TEST/BETA 0.1.0 2023-09-23]] (Windows x86_64, Mac x86_64/aarch64, Linux x86_64 binaries included) 457ebdec59d6a917268f669d8661700852f74f82 3204 3203 2023-09-23T23:16:17Z Darc 1 wikitext text/x-wiki '''Redump2CDI''' is a utility created by [[darc]] to convert Redump Dreamcast CD-ROM images to [[DiscJuggler]] format. The Redump image format is a non-standard form of BIN+CUE image that cannot be burned or mounted with much existing software, so conversion is convenient for non-archival purposes. Redump2CDI is intended only for Redump Dreamcast CD-ROM images. It is not intended to convert GD-ROM images or old schoool non-selfboot BIN+CUE Dreamcast files. * Download: [[:File:Redump2cdi-0.1.0-2023-09-23.zip|Redump2CDI TEST/BETA 0.1.0 2023-09-23]] (Windows x86_64, Mac x86_64/aarch64, Linux x86_64 binaries included) To use, run like so: redump2cdi -i "My Favorite Game (Unl).cue" -o myfavgame.cdi 98663fe02c7c508a1fca2f81c8e445d4016e2909 3205 3204 2023-09-24T00:04:54Z Darc 1 wikitext text/x-wiki '''Redump2CDI''' is a utility created by [[darc]] to convert Redump Dreamcast CD-ROM images to [[DiscJuggler]] format. The Redump image format is a non-standard form of BIN+CUE image that cannot be burned or mounted with much existing software, so conversion is convenient for non-archival purposes. Redump2CDI is intended only for Redump Dreamcast CD-ROM images. It is not intended to convert GD-ROM images or old schoool non-selfboot BIN+CUE Dreamcast files. This is a beta version. * Download: [[:File:Redump2cdi-0.1.0-2023-09-23.zip|Redump2CDI TEST/BETA 0.1.0 2023-09-23]] (Windows x86_64, Mac x86_64/aarch64, Linux x86_64 binaries included) To use, run like so: redump2cdi -i "My Favorite Game (Unl).cue" -o myfavgame.cdi 8f8a12698307b07e57a7e7bf83faed3189c2bb91 File:Redump2cdi-0.1.0-2023-09-23.zip 6 1399 3202 2023-09-23T23:09:32Z Darc 1 Uploaded own work with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Redump2CDI TEST/BETA 0.1.0 2023-09-23}} |date=2023-09-23 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 7d75eefc5269cf64f0b20c745046ef840f057d76 32MB RAM expansion 0 284 3206 3184 2023-09-28T15:54:51Z Darc 1 /* Emulators */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issues are 1. Sofdec video playback in commercial games and 2. Windows CE. Games using Sofdec video will fail to play FMV, crashing and rebooting the console as a result. Windows CE games will not boot and either hang or reboot the system. More research is needed to determine if these issues can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===KallistiOS=== [[KallistiOS]] currently supports 32MB expansion when using the GCC 4.7.4 (current stable) or GCC 9.3.0 (current testing) toolchains. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> KallistiOS also includes [https://github.com/KallistiOS/KallistiOS/tree/master/examples/dreamcast/basic/memtest32 memtest32] in its example programs. Adapted from tsowell's original utility, memtest32 supports memory testing 16MB and 32MB Dreamcasts. ===DreamShell=== The latest version of the [[DreamShell]] operating system, which uses KallistiOS as its kernel, now supports 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X ==Emulators== ===Flycast=== Support has been [https://github.com/flyinghead/flycast/pull/1198 added to the development version of Flycast]. ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when run with the <code>--ram-size=32</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir meson compile -C builddir ./builddir/lxdream-nitro --ram-size=32 45afcbcbb77b3f8c6135d0c077b441bc4b9f7b0a 3207 3206 2023-09-28T15:58:32Z Darc 1 /* KallistiOS */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> By replacing the Dreamcast's two 8MB SDRAM chips with larger SDRAM chips, modifying the pin arrangement, and [[BIOS modification|modifying the BIOS]], it is possible to install 32MB of system RAM in the Dreamcast. ==Installation== It is necessary to replace the stock read-only boot ROM with a writeable flash ROM, as without patching the BIOS to address the modified memory arrangement, the system will not boot with RAM in a 32MB configuration. The mod has only been tested so far using <code>IS42S32800J-6TL</code> replacement chips. These are readily available online, e.g. at [https://www.mouser.com/ProductDetail/ISSI/IS42S32800J-6TL Mouser] or [https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S32800J-6TL/5319845 DigiKey]. [https://blog.ldtlb.com/2020/06/21/dreamcast-32mb-ram-upgrade.html tsowell's blog] contains instructions on completing the RAM upgrade. ===BIOS Flasher=== A DreamShell image with 32MB-patched BIOS images is available. This image contains a variety of nearly 50 BIOS images including the stock BIOS, japanese-cake BIOS, DreamBoot BIOS, and DreamShell BIOS, in a variety of flavors for each. This image also contains an updated bflash.klf module to support flashing MX29L3211 32 megabit chips to accommodate multi-BIOS mods. * We are not responsible for damage to Dreamcast units due to the use of this disc. Know what you are doing before you use this disc! You may render your system unbootable! ** Download [https://mega.nz/file/CipDkAiJ#jTMqXza0jpI053euIBodJUcClO7H0B-Ur9tIjcOgopE DreamShell 32MB BIOS Flasher Image] ==Incompatibility issues== Existing games and applications predating this RAM expansion modification will not be able to take advantage of the additional memory. Adoption of the mod is not yet widespread, so additional testing is needed. At this time, the major incompatibility issues are 1. Sofdec video playback in commercial games and 2. Windows CE. Games using Sofdec video will fail to play FMV, crashing and rebooting the console as a result. Windows CE games will not boot and either hang or reboot the system. More research is needed to determine if these issues can be fixed in patches. Games that don't use Sofdec video appear to work without problem, even including other types of video like the 4XM video used in [[Headhunter]]. ==Applications== ===KallistiOS=== [[KallistiOS]] [https://github.com/KallistiOS/KallistiOS/pull/82 supports] the 32MB expansion mod. Applications built will function on 16MB or 32MB systems, but the programmer can support features with heavier memory use on 32MB systems. The following code block provides a primer on the use: <syntaxhighlight lang="c">/* HW_MEM_16 and HW_MEM_32 macros define the memory sizes KallistiOS supports */ printf("KallistiOS supports systems with %d or %d bytes of memory installed.\n", HW_MEM_16, HW_MEM_32); /* The HW_MEMSIZE macro can be called to retrieve the running system's size */ printf("HW_MEMSIZE reports this system has %ld bytes.\n", HW_MEMSIZE); printf("This is a %s console!\n", (HW_MEMSIZE == HW_MEM_32 ? "32MB" : "16MB" )); /* The DBL_MEM boolean macro is provided as a fast way to determine if the extra RAM is available */ printf("Does the system have double RAM? %s\n", (DBL_MEM ? "Yes!" : "No...")); /* uint32 _arch_mem_top can be used to get the top address of memory */ printf("Top of memory is 0x%0lx!\n", _arch_mem_top); /* 0x8e000000 if 32MB, 0x8d000000 if 16MB */</syntaxhighlight> KallistiOS also includes [https://github.com/KallistiOS/KallistiOS/tree/master/examples/dreamcast/basic/memtest32 memtest32] in its example programs. Adapted from tsowell's original utility, memtest32 supports memory testing 16MB and 32MB Dreamcasts. ===DreamShell=== The latest version of the [[DreamShell]] operating system, which uses KallistiOS as its kernel, now supports 32MB expansion. ===NetBSD Support=== NetBSD can be easily modified to support the 32MB expansion by modifying the <code>sys/arch/dreamcast/conf/std.dreamcast</code> file and rebuilding. Replace options IOM_RAM_SIZE=0x01000000 # 16MB with options IOM_RAM_SIZE=0x02000000 # 32MB and rebuild the kernel. ===ScummVM=== tsowell has written a [https://github.com/tsowell/scummvm-dreamcast fork of ScummVM] with extra functionality which is able to play larger games on consoles with 32MB expansion. This version of [[ScummVM]] also offers an extensive array of other expansion hardware features, such as compatibility for loading/saving data with [[Serial SD card adapter|SD cards]] and [[IDE hard drive modification|hard drives]], the ability to output MIDI over [[MIDI adapter|serial]] or [[MIDI expansion|the expansion slot]] for external synthesizers, and the ability to output various VGA modes for CRT monitors. ===Game mods=== A few game mods by [[yzb]] exist to increase performance: * The King of Fighters '98 * King of Fighters XI (Atomiswave conversion) * Knights of Valour The Seven Spirits (Atomiswave conversion) * Super Street Fighter II X ==Emulators== ===Flycast=== Support has been [https://github.com/flyinghead/flycast/pull/1198 added to the development version of Flycast]. ===lxdream Dreamcast Emulator=== [https://gitlab.com/simulant/community/lxdream-nitro lxdream-nitro] supports 32MB expansion when run with the <code>--ram-size=32</code> option. git clone https://gitlab.com/simulant/community/lxdream-nitro.git cd lxdream-nitro meson setup builddir meson compile -C builddir ./builddir/lxdream-nitro --ram-size=32 8d3a92e51bb3a86fc067a328c7d2c124bcd54c66 DCWiki:Software 4 81 3208 1795 2023-10-02T17:42:22Z Darc 1 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * [[Online Services]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Engine & Library]] ** [[Tools and Utilities]] ** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation] * [[VMU development]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[Useful programming tips]] * [[NetBSD/Dreamcast]] |} |} 3e7c1a3ddd897973fb1c87946c5d6f00f70bf8d2 SH4 in Compiler Explorer 0 733 3209 3198 2023-10-07T05:57:38Z BBHoodsta 2 /* Convenience Templates */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: compile code for the processor in little-endian mode * <code>-m4-single-only</code>: generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). * <code>-matomic-model=soft-imask</code>: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations * <code>-ftls-model=local-exec</code>: enables the model used by KOS for supporting variables declared with the "thread_local" keyword = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/rafvMdWGb C2X Hello World] ** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] ARM GCC8.5 ** [https://godbolt.org/z/as55qv3qT C Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 79a513993bee35d239e1dc9b941ee920d8e9f30c 3210 3209 2023-10-07T05:58:31Z BBHoodsta 2 /* Convenience Templates */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: compile code for the processor in little-endian mode * <code>-m4-single-only</code>: generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). * <code>-matomic-model=soft-imask</code>: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations * <code>-ftls-model=local-exec</code>: enables the model used by KOS for supporting variables declared with the "thread_local" keyword = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/rafvMdWGb C2X Hello World] ** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] Pre-configured template for ARM GCC8.5, Dreamcasts sound chip ** [https://godbolt.org/z/as55qv3qT C Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 688a77ad88bc1beeed4aca8c0c2629c55491b9b6 3211 3210 2023-10-07T06:00:03Z BBHoodsta 2 /* Convenience Templates */ wikitext text/x-wiki Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with [https://godbolt.org Compiler Explorer], along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast. = Configuration = [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: * <code>-ml</code>: compile code for the processor in little-endian mode * <code>-m4-single-only</code>: generate code for the SH4 with a floating-point unit that only supports single-precision arithmetic * <code>-ffast-math</code>: breaks strict IEEE compliance and allows for faster floating point approximations * <code>-O3</code>: optimization level 3 * <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4). * <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4). * <code>-matomic-model=soft-imask</code>: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations * <code>-ftls-model=local-exec</code>: enables the model used by KOS for supporting variables declared with the "thread_local" keyword = Convenience Templates = [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] The following are pre-configured templates you can use as sample Dreamcast build configurations: * GCC4.9.4: ** [https://godbolt.org/z/9MKzeMfMj C11 Hello World] ** [https://godbolt.org/z/qGzoeo4sj C++14 Hello World] * GCC9.5.0: ** [https://godbolt.org/z/rvW3s3594 C17 Hello World] ** [https://godbolt.org/z/qYfE5G6Mx C++17 Hello World] * GCC12.2.0: ** [https://godbolt.org/z/94TKvxazn C17 Hello World] ** [https://godbolt.org/z/61jqhE3zn C++20 Hello World] * GCC13.1.0: ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] * GCC13.2.0: ** [https://godbolt.org/z/rafvMdWGb C2X Hello World] ** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] Pre-configured template for ARM GCC8.5, Dreamcasts sound chip ** [https://godbolt.org/z/895dWG9qf C Hello World] = Tips and Notes = * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. 08f986140c55f7ec202a31070952c4bd92e9937e Setting up Flycast GDB 0 1400 3212 2023-10-07T12:47:05Z Colton 161 Created page with "=== Clone dev branch of Flycast === git clone https://github.com/flyinghead/flycast -b dev cd flycast git submodule update --init --recursive === Build with GDB Support === mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GDB_SERVER=ON .. make -j$(nproc) === Enable GDB in Config File === Briefly launch Flycast to make sure config file exists ./flycast Edit config file to enable GDB Path on Linux: ~/.config/flycast/emu.cfg Under "[config]" make..." wikitext text/x-wiki === Clone dev branch of Flycast === git clone https://github.com/flyinghead/flycast -b dev cd flycast git submodule update --init --recursive === Build with GDB Support === mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GDB_SERVER=ON .. make -j$(nproc) === Enable GDB in Config File === Briefly launch Flycast to make sure config file exists ./flycast Edit config file to enable GDB Path on Linux: ~/.config/flycast/emu.cfg Under "[config]" make sure GDBEnabled is set to yes [config] ... Debug.GDBEnabled = yes Debug.GDBPort = 3263 ... === Start GDB Session === Start a gdb with SH4 support, I use gdb-multiarch from my package manager gdb-multiarch In the GDB shell run the following commands to configure the GDB session set arch sh4 set endian big Start Flycast Emulation and then connect to running core target remote :3263 This will pause execution of the game upon connecting From here you can set breakpoints, instruction step, and read/write memory using normal GDB commands Handy reference: [https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf GDB Cheat Sheet] The following commands show a terminal interface of the registers and instructions: layout asm on layout regs on Single Instruction Step nexti Pressing Enter with no command typed will just repeat the last command (good for stepping) 0292716814e51d9375494df135560b09fd6fb01c 3213 3212 2023-10-09T21:23:29Z Colton 161 wikitext text/x-wiki === Clone dev branch of Flycast === git clone https://github.com/flyinghead/flycast -b dev cd flycast git submodule update --init --recursive === Build with GDB Support === mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GDB_SERVER=ON .. make -j$(nproc) === Enable GDB in Config File === Briefly launch Flycast to make sure config file exists ./flycast Edit config file to enable GDB Path on Linux: ~/.config/flycast/emu.cfg Under "[config]" make sure GDBEnabled is set to yes [config] ... Debug.GDBEnabled = yes Debug.GDBPort = 3263 ... === Start GDB Session === Start a gdb with SH4 support, I use gdb-multiarch from my package manager gdb-multiarch In the GDB shell run the following commands to configure the GDB session set arch sh4 set endian big </br></br> '''Note:''' If run in big endian mode, even and odd instructions will be swapped. This can be worked around by changing lines 37 & 38 in <code>code/debug/debug_agent.h</code> to: #define SWAP_32(a) (a) #define SWAP_16(a) (a) And then use <code>set endian little</code> and GDB will work as expected. </br></br></br> Start Flycast Emulation and then connect to running core target remote :3263 This will pause execution of the game upon connecting From here you can set breakpoints, instruction step, and read/write memory using normal GDB commands Handy reference: [https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf GDB Cheat Sheet] The following commands show a terminal interface of the registers and instructions: layout asm on layout regs on Single Instruction Step nexti Pressing Enter with no command typed will just repeat the last command (good for stepping) cd822f931a6daaf3b691b6020d483c580c4c32fc 3219 3213 2023-10-12T15:47:49Z Colton 161 wikitext text/x-wiki === Clone dev branch of Flycast === git clone https://github.com/flyinghead/flycast -b dev cd flycast git submodule update --init --recursive === Build with GDB Support === mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GDB_SERVER=ON .. make -j$(nproc) === Enable GDB in Config File === Briefly launch Flycast to make sure config file exists ./flycast Edit config file to enable GDB Path on Linux: ~/.config/flycast/emu.cfg Under "[config]" make sure GDBEnabled is set to yes [config] ... Debug.GDBEnabled = yes Debug.GDBPort = 3263 ... === Start GDB Session === Start a gdb with SH4 support, I use gdb-multiarch from my package manager gdb-multiarch In the GDB shell run the following commands to configure the GDB session set arch sh4 set endian little Start Flycast Emulation and then connect to running core target remote :3263 This will pause execution of the game upon connecting From here you can set breakpoints, instruction step, and read/write memory using normal GDB commands Handy reference: [https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf GDB Cheat Sheet] The following commands show a terminal interface of the registers and instructions: layout asm on layout regs on Single Instruction Step nexti Pressing Enter with no command typed will just repeat the last command (good for stepping) a247bde73f31ec2c76990614cdebc7095ab14bdd User:Einsteinx2 2 1401 3214 2023-10-10T22:33:56Z Einsteinx2 6 Created page with "https://github.com/einsteinx2" wikitext text/x-wiki https://github.com/einsteinx2 23aa143fa877237183821d7577f08e9ec8a12ee8 MR image 0 73 3215 1034 2023-10-11T00:16:38Z Darc 1 /* Encoding Algorithm */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===File Header=== {| class="wikitable" style="text-align: center" |- ! Size (bytes) !! Contents |- | 2 |style="text-align: left;"| "MR" |- | 4 |style="text-align: left;"| Total file size |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Image data offset in bytes (Header size + Palette size) |- | 4 |style="text-align: left;"| Image width |- | 4 |style="text-align: left;"| Image height |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, size): length = 0 position = 0 run = 0 while(position < size): run = 1 while((run < 0x17f) and (position+run < size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> f1e4381631293e1d82fce96509c22d657b8ca323 3216 3215 2023-10-11T00:18:47Z Darc 1 /* Decoding Algorithm */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===File Header=== {| class="wikitable" style="text-align: center" |- ! Size (bytes) !! Contents |- | 2 |style="text-align: left;"| "MR" |- | 4 |style="text-align: left;"| Total file size |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Image data offset in bytes (Header size + Palette size) |- | 4 |style="text-align: left;"| Image width |- | 4 |style="text-align: left;"| Image height |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, size): length = 0 position = 0 run = 0 while(position < size): run = 1 while((run < 0x17f) and (position+run < size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # cdata_size: Size of input in bytes # idata_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, cdata_size, idata_size): position = 0 idx_position = 0 run = 0 indexed_data = array("B", "\x00" * idata_size) while(position < cdata_size): first_byte = input[position] if((position+1) < cdata_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): # The additional byte (+ 1) is useless, but it always present in MR files. if(idx_position+i < idata_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> 417aff80da9b5f03a172df205cc06ce0390193a6 3217 3216 2023-10-11T00:19:53Z Darc 1 /* Encoding Algorithm */ wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===File Header=== {| class="wikitable" style="text-align: center" |- ! Size (bytes) !! Contents |- | 2 |style="text-align: left;"| "MR" |- | 4 |style="text-align: left;"| Total file size |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Image data offset in bytes (Header size + Palette size) |- | 4 |style="text-align: left;"| Image width |- | 4 |style="text-align: left;"| Image height |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, size): length = 0 position = 0 run = 0 while(position < size): run = 1 while((run < 0x17f) and (position+run < size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # cdata_size: Size of input in bytes # idata_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, cdata_size, idata_size): position = 0 idx_position = 0 run = 0 indexed_data = array("B", "\x00" * idata_size) while(position < cdata_size): first_byte = input[position] if((position+1) < cdata_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): # The additional byte (+ 1) is useless, but it always present in MR files. if(idx_position+i < idata_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> 9856cfa01ae088e4e644fef636f139d8787aeb75 3218 3217 2023-10-11T00:23:30Z Darc 1 Reverted edits by [[Special:Contributions/Darc|Darc]] ([[User talk:Darc|talk]]) to last revision by [[User:Unknown user|Unknown user]] wikitext text/x-wiki ==About== A MR image is an image format solely used inside an [[IP.BIN]] file to show off a logo during the boot screen process of the Sega Dreamcast. [[File:Windows CE boot screen.png|thumb|Games powered by Windows CE boot screen]]This image format was used in commercialized Dreamcast games utilizing Windows CE SDK where we see a "Powered by Microsoft Windows CE" logo. It is now commonly used in homebrew to distinguish the creator(s) of the application or to disassociate the application being produced by or under license from Sega. The MR image must be inserted into a [[IP.BIN]] file at offset '''0x3820''' in order to be viewed during boot sequence. Since [[IP.BIN]] is restricted to a 32k file size, there are a couple of guidelines the MR image must meet to in order to fit inside the [[IP.BIN]]. <br/> '''MR Image must be:''' * '''320x90''' or less * Max '''128''' colors * Less than '''8192''' bytes to fit in a IP.BIN * The transparent color is '''#c0c0c0''', or 192, 192, 192 in RGB <br/> ==Tools== '''Selfboot-Inducer''' SiZious's Windows [https://sizious.com/download/dreamcast/#selfboot-inducer Tool] to create homebrew compilations. Using this application you can view and create MR images from other various other image formats. <br/> '''MR GIMP Plugin''' [https://www.gimp.org/ GIMP] is a cross-platform image editor available for GNU/Linux, OS X, Windows. Using this GIMP plugin([https://gitlab.com/BBHoodsta/makeip "file-mr.py"]), you can create view, edit, and create a MR image from any other image format that GIMP supports. ==File Format== The file format is composed of three sections: '''Header''', '''Palette''', and the '''Image Data'''. All of the data written in the file is in '''little-endian''' format. A MR file starts off with a 30 byte header. ===File Header=== {| class="wikitable" style="text-align: center" |- ! Size (bytes) !! Contents |- | 2 |style="text-align: left;"| "MR" |- | 4 |style="text-align: left;"| Total file size |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Image data offset in bytes (Header size + Palette size) |- | 4 |style="text-align: left;"| Image width |- | 4 |style="text-align: left;"| Image height |- | 4 |style="text-align: left;"| Crap (fill with 0's) |- | 4 |style="text-align: left;"| Amount of colors in palette |} ===Palette=== The header is followed by the image's palette. The palette is composed of palette entries where each palette entry is 4 bytes long and is stored as BGRA. The alpha byte goes unused. The maximum number of palette entries is '''128'''. {| class="wikitable" |- ! colspan="4"|Palette Entry |- | B || G || R || A |} In total, the byte size of your palette should be number of colors * 4. ===Image Data=== Lastly, the image data. The image data is basically an array of indices, each a byte long, that refers to a palette entry in the palette. The image data is compressed using a form of Run-Length Encoding (RLE). The python algorithms to encode/decode the image data are shown below. ==Encoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # output: Byte array # input_size: Size of input in bytes (image width * image height) # returns: Size of the compressed data def mr_encode(input, output, input_size): run = 0 length = 0 position = 0 while(position < input_size): run = 1 while((run < 0x17f) and (position+run < input_size) and (input[position] == input[position+run])): run += 1 if(run > 0xff): output[length] = 0x82 length += 1 output[length] = 0x80 | (run - 0x100) length += 1 output[length] = input[position] length += 1 elif(run > 0x7f): output[length] = 0x81 length += 1 output[length] = run length += 1 output[length] = input[position] length += 1 elif(run > 1): output[length] = 0x80 | run length += 1 output[length] = input[position] length += 1 else: output[length] = input[position] length += 1 position += run return length </syntaxhighlight> ==Decoding Algorithm== <syntaxhighlight lang="c" line="line"> # input: Byte array # input_size: Size of input in bytes # uncompressed_size: Size of uncompressed data in bytes (image width * image height) # returns: Decoded image data def mr_decode(input, input_size, uncompressed_size): run = 0 position = 0 idx_position = 0 indexed_data = array("B", "\x00" * uncompressed_size) while(position < input_size): first_byte = input[position] if((position+1) < input_size): second_byte = input[position+1] # The bytes lower than 0x80 are recopied just as they are in the Bitmap if(first_byte < 0x80): run = 1 position += 1 # The tag 0x81 is followed by a byte giving directly the count of points elif(first_byte == 0x81): run = second_byte first_byte = input[position+2] position += 3 # The tag 0x82 is followed by the number of the points decoded in Run # By retaining only the first byte for each point elif(first_byte == 0x82 and second_byte >= 0x80): run = second_byte - 0x80 + 0x100 first_byte = input[position+2] position += 3 else: run = first_byte - 0x80 first_byte = second_byte position += 2 # Writing decompressed bytes for i in range(run): if(idx_position+i < uncompressed_size): indexed_data[idx_position+i] = first_byte idx_position += run return indexed_data </syntaxhighlight> 603377db9b2645d9a03551c0b1fcf5ff7e87b55b Useful programming tips 0 269 3220 952 2023-10-14T08:21:14Z GyroVorbis 13 I'm sorry, but the way this is worded is just not quite correct. He's talking about aspects of the processor, but he's making it sound like modern software PARADIGMS and practices don't apply to DC, when in reality we have C++20 and even all of the async, concurrent crap used in multicore working just fine. wikitext text/x-wiki The Dreamcast's CPU, model SH7091, is virtually identical to the Renesas SH7750 series of SH4 CPUs. As such, anything that would normally apply to the SuperH-4 architecture applies here. Given that the SH4 is a processor from 1998, many hardware features that we have grown accustomed to on more recent x86 and ARM64 processors either do not apply or behave much more primitively on the SH4. For example, SH4 does not have branch prediction, speculative execution, or multiple cores, but it does have a 64-bit floating point unit,<ref>It's predominantly used for single-precision operations: it ''can'' do doubles, but that doesn't mean it's a great idea!</ref> a couple of 128-bit vector operations on 4x packed 32-bit floats,<ref>See fipr, ftrv: http://www.shared-ptr.com/sh_insns.html</ref> a memory management unit (MMU), and a direct memory access controller (DMAC). In truth, at a very basic level the SH4 architecture is fundamentally not that different from these other, more mainstream architectures (in fact, ARM Thumb is based on SuperH<ref>https://lwn.net/Articles/647636/</ref>), so programming on the SH4 does not require much in the way of "re-learning" how to do things, especially since the Dreamcast uses it in little endian mode exclusively. Mainly, SH4 programming just requires paying a lot more attention to things that modern architectures have made very convenient, like data alignment, cache management, and pipelining. The following page is a collection of programming tips and tricks to help with optimizing programs to make full use of the SH4 CPU. '''''This is not meant to be a substitute for reading the SH7750 series hardware and software manuals,''''' rather it should be seen more as an additional reference based on experiences working with the chip (and, in fact, certain terms and hardware-specific concepts assume familiarity with those manuals). Both manuals, "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" and "SH-4 Software Manual," can be downloaded from the "Documents" section of any SH7750 series processor's product page on Renesas's website: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/superh/sh7750/sh7750r.html, and the SH4 C ABI on STMicroelectronics's website, "RM0197: SH-4 generic and C specific application binary interface," is incredibly handy, too--search for RM0197: https://www.st.com/content/st_com/en.html. A very convenient SuperH assembly reference can be found here, as well: http://www.shared-ptr.com/sh_insns.html. This page refers to the documents as follows: * SH7750 Hardware Manual: "SH7750, SH7750S, SH7750R Group User's Manual: Hardware" * SH7750 Software Manual: "SH-4 Software Manual" * SH4 C ABI: "RM0197: SH-4 generic and C specific application binary interface" == Alignment == (Refer to: SH7750 Hardware Manual, Section 5 "Exceptions") The SH4 lives and dies by alignment, and very strictly requires data to be aligned according to its type in memory. Crashes will otherwise ensue. Take the following example, which defines a packed structure aligned to 4 bytes: <syntaxhighlight lang="c"> typedef struct __attribute__ ((packed, aligned(4))) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; </syntaxhighlight> Accessing data from this struct is pretty simple, it should just need a simple 4-byte access. This works because the struct is aligned to 4 bytes. Doing this: <syntaxhighlight lang="c"> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </syntaxhighlight> Produces this output (GCC 9.2.0): <syntaxhighlight lang="objdump">420 02e4 862F mov.l r8,@-r15 421 02e6 4365 mov r4,r5 422 02e8 962F mov.l r9,@-r15 423 02ea 0C75 add #12,r5 424 02ec 224F sts.l pr,@-r15 425 02ee 4159 mov.l @(4,r4),r9 426 02f0 4256 mov.l @(8,r4),r6 427 02f2 12D0 mov.l .L71,r0 428 02f4 9869 swap.b r9,r9 429 02f6 6866 swap.b r6,r6 430 02f8 11D4 mov.l .L72,r4 431 02fa 6966 swap.w r6,r6 432 02fc 9969 swap.w r9,r9 433 02fe 9869 swap.b r9,r9 434 0300 6868 swap.b r6,r8</syntaxhighlight> But what if it weren't aligned to 4 bytes? Just this: <syntaxhighlight lang="c"> typedef struct __attribute__ ((packed)) { unsigned char id[4]; unsigned int address; unsigned int size; unsigned char data[]; // Flexible array member } command_t; </syntaxhighlight> Accessing the data looks like this, in that case (GCC 9.2.0): <syntaxhighlight lang="objdump">555 03f0 862F mov.l r8,@-r15 556 03f2 4365 mov r4,r5 557 03f4 962F mov.l r9,@-r15 558 03f6 0C75 add #12,r5 559 03f8 224F sts.l pr,@-r15 560 03fa 4484 mov.b @(4,r4),r0 561 03fc 0C63 extu.b r0,r3 562 03fe 4584 mov.b @(5,r4),r0 563 0400 0C61 extu.b r0,r1 564 0402 4684 mov.b @(6,r4),r0 565 0404 1861 swap.b r1,r1 566 0406 0C60 extu.b r0,r0 567 0408 3B21 or r3,r1 568 040a 2840 shll16 r0 569 040c 0B21 or r0,r1 570 040e 4784 mov.b @(7,r4),r0 571 0410 2840 shll16 r0 572 0412 1840 shll8 r0 573 0414 1B20 or r1,r0 574 0416 0869 swap.b r0,r9 575 0418 4884 mov.b @(8,r4),r0 576 041a 9969 swap.w r9,r9 577 041c 0C63 extu.b r0,r3 578 041e 4984 mov.b @(9,r4),r0 579 0420 9869 swap.b r9,r9 580 0422 0C62 extu.b r0,r2 581 0424 4A84 mov.b @(10,r4),r0 582 0426 2862 swap.b r2,r2 583 0428 0C60 extu.b r0,r0 584 042a 3B22 or r3,r2 585 042c 2840 shll16 r0 586 042e 0B22 or r0,r2 587 0430 4B84 mov.b @(11,r4),r0 588 0432 12D4 mov.l .L73,r4 589 0434 2840 shll16 r0 590 0436 1840 shll8 r0 591 0438 2B20 or r2,r0 592 043a 0860 swap.b r0,r0 593 043c 0961 swap.w r0,r1</syntaxhighlight> All of this is just from this simple operation: <syntaxhighlight lang="c"> unsigned int cmd_addr = ntohl(command->address); unsigned int cmd_size = ntohl(command->size); </syntaxhighlight> What's going on here is GCC is avoiding an address alignment crash that would occur from accessing 1-byte-aligned data. This is because struct packing aligns to 1 byte, and GCC needs to do the following process to build an unsigned 4-byte integer from 1-byte accesses: <syntaxhighlight lang="asm"> mov.b, zero-extend mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add mov.b, zero-extend, shift, add </syntaxhighlight> (Note: all the swap instructions come from ntohl, as this code is from a network driver that needs to byte swap data after receiving a network transmission.) Considering that 1x mov.b takes the same amount of time as 1x mov.l, plus all the other operations that must be done to build the 4-byte data out of 1-byte accesses, it's easy to see how big the performance hit from mismanaging alignment can be! == Cache Management == (Refer to: SH7750 Hardware Manual, Section 4 "Caches" and SH7750 Software Manual, Section 9 "Instruction Descriptions") Unlike modern processors, where caches are several megabytes in size and can therefore hold entire programs, the SH4 in the Dreamcast only has a 16kB data cache and 8kB instruction cache. Consequently, cache management is very important in order to achieve maximum performance. As is always true of cache optimization, write-back memory mode is required to make much use of it (it's used everywhere by default in [[KallistiOS]] and enabled for P0/U0/P3--but not P1--in [[DreamHAL]]'s startup file). Half of the data cache can also be used as a form of high-speed RAM (referred to as OCRAM), but in most cases programs should stick to using the full cache size for cache purposes. The SH4 uses a direct-mapped cache, meaning that there is only one cache entry for every 16kB memory chunk (half that when used in OCRAM mode) and cache trashing can happen if trying to do something like copy data from some address to a destination address that is an integer multiple of the cache size away from that address (e.g. source = address offset 8 and destination = address 16kB + 8). The SH4 provides the following instructions in addition to the two 32-byte "store queues" (SQs) to make efficient use of the cache: * '''movca.l:''' Store register data to cache, if there's a cache miss just allocate a cache block and write to it without first reading that cache block from memory * '''ocbp:''' Purge cache block; write back cache block and invalidate it * '''ocbi:''' Invalidate cache block without writing it back * '''ocbwb:''' Write cache block back to external memory, and keep it in the cache == C Function Register Allocation == (Refer to: SH4 C ABI) (Note: when using GCC 9.x at various optimization levels, like -O3, it tries its best to coalesce output code into this format wherever it can. Of course, if GCC is able to inline a function, parameter-passing becomes a moot point.) The SH4 C ABI specifies that 4 integers (r4-r7) and 8 floats (fr4-fr11) can be passed in registers as function call arguments, and that r0-r3 and fr0-fr3 are also call-clobbered. Passing arguments in registers means that functions can take 4 integers and 8 floats without forcing arguments to be pushed on the stack, saving the cycle penalties that would otherwise occur from stack pushes and associated memory accesses. The call-clobbering of r0-r3 and fr0-fr3 means that those can be used as 4 integer local variables and 4 float variables, as well. Additionally, any of these registers not used for parameters can be repurposed as local variables, so if one only needs to pass in 4 floats to a function, one can then define 4 more local variable floats on top of the 4 we get from fr0-fr3 and they will just use the unused registers. == Pipelining and Instruction-Level Parallelism == (Refer to: SH7750 Hardware Manual, Section 8 "Pipelining") This section is really only relevant when writing assembly. If you write code in a high-level language like C/C++, compilers [try to] take of this for you and there isn't much you can do about it. Because of the SH4's dual-issue superscalar design, the CPU preloads two instructions at once, and under the right circumstances these instructions can be executed in parallel. The SH4 architecture organizes various instructions into "instruction groups," and parallel execution primarily occurs when two instructions of different groups are issued together. There are a variety of special cases to this rule of thumb, however, and more advanced code can be structured to take advantage of these properties. For example, if the two instructions are of different groups but have a dependency chain, the second instruction will stall into the next cycle, and there is also the fact that CO group instructions do not parallelize with anything. Conversely, there are special cases like 0-cycle instructions that can execute in parallel ''despite'' having dependency chains (e.g. a "mov Rn, Rm" followed by an "add #imm8, Rm"), and MT group instructions that can parallelize with other MT group instructions (unless there's a non-special-case dependency chain). Appropriate usage of instruction-level parallelism is the only way to achieve >200 MIPS (millions of instructions per second) on a 200MHz SH4. == References == 1fd802480c5e40559a987d5c80b2b3b6c9508f5c User:Colton 2 1402 3221 2023-10-14T16:14:29Z Darc 1 Created page with "https://github.com/cepawiel" wikitext text/x-wiki https://github.com/cepawiel e06324133b0228f5a691de2ce6944dd83a0e2295 Fast SH4 Vertex Processing 0 84 3226 1584 2023-11-10T06:25:10Z Darc 1 /* Vector Math Instructions */ wikitext text/x-wiki [http://yam.20to4.net/dreamcast/hints/index.html Original source] ==Vector Math Instructions== The SH4 CPU features some nice builtin math operations. I saw some people trying to speed up their code by using approximations with integer codes and other tricks. That may work but on the SH4 good code that makes use of the builtin instructions will outperform in the most situations. There is not much sense in trying to replace that functions at all since they are already pretty fast. ===<code>FIPR</code>=== Computes the dot product of two 4D vectors <code>x1*x2 + y1*y2 + z1*z2 + w1*w2</code> Often used in lighting formulas. ===<code>FTRV</code>=== Muliplies a 4x4 matrix with a 4D vector Usually used to transform vertices, but can also be used to compute "a * b + c" for four floats in parallel. However, the FMAC may perform better in particular situations because the matrix needs to be setup in a special way. ===<code>FSRRA</code>=== Approximates <code>1.0f / sqrt (x)</code> Usually used to normalize a vector. ===<code>FSCA</code>=== Approximates the sine and cosine. Comes in handy when constructing rotation matrices. This one takes the angle as an integer in the range 0...32767 so it's best to redefine angle representations throughout the whole code so that an angle of PI = 16384 or something. This would save the required conversion (range scale and truncation to integer). ===<code>FSQRT</code>=== Computes <code>sqrt (x)</code> This is actually not a special instruction but it's there and comes in handy sometimes although it's slower than FSRRA so rewrite your math formulas (e.g. range falloff lighting) and try to use FSRRA where applicable instead. ===<code>FMAC</code>=== Computes <code>a * b + c</code> This is as fast as normal float addition, subtraction or multiplication, so basically you pay one and get another operation for free. Comes in handy when doing linear interpolation (polygon clipping, table lookups etc). ===<code>FMOV</code> (64 bit)=== This instruction is very important since it can access the second banked set of the FPU registers that are normally used to hold the vector transformation matrix. It's best to avoid switching the fmov mode very often, so rearrange your data layout. It also requires the data to be 64 bit aligned (8 bytes). ==Cache== The cache is very very important. It is so important that it may either save your day or screw up everything. First of all it is important to understand how the cache works. It is a direct mapped cache, i.e. the cache lines are mapped directly onto the addresses of the memory and since it's only 16 KB small the memory at address (n) is mapped onto the same cache line as the location at address (n + 1024*16) which will result in a cache miss. So it's best to avoid such situations which is not always possible especially when working with large amounts of data, e.g. vertex data. That's where the powerful cache control instructions come in... ===<code>PREF</code>=== Prefetches a cache line for the specified address Use this to prefetch the next element in processing loops for large data buffers. The prefetch delay can be hidden by prefetching the next element at the beginning of the loop. ===<code>OCBWB</code>=== Writes back a cache line This one is often used when cache content and memory content need to be synchronized explicitely for DMA transfers since the DMA controllers operate directly on memory. ===<code>OCBI</code>=== Invalidates a cache line This is also used often with DMA functions before reading a memory area that had just been rewritten by a DMA controller. Another way would be to access the memory area as uncached but this might slow down everything. ===<code>OCBP</code>=== Purges a cache line (write back & invalidate) Use this one after your processing loop definitely has finished its operations for one element. The effect is very similar to the store queues except that you cannot read anything from the store queue lines and can write only 32 or 64 bits at once. ===<code>MOVCA.L</code>=== Allocates a cache line for the specified address This one is very important when processing large buffers. While the OCBP instruction can be left out wihtout any performance drops this is does not apply for MOVCA.L. When processing large buffers you often have an input buffer and an output buffer. The input buffer is read, something is done with the elements and they are stored into the output buffer. Without MOVCA.L a store to the output buffer would cause the cache to read a cache line from the output buffer and redirect the store into the cache. This is a total waste, because most of time every byte of the output buffer is only rewritten with new content. That's what the MOVCA.L is for. It tells the cache to reserve a cache line without fetching memory. But be careful this may cause data corruption. There is another cache feature which makes it possible to use half of the operand cache (i.e. 8 KB) as scratchpad RAM. This may be used to hold transformation loop parameters like matrices or something but it also halves the operand cache size which may decrease overall performance of the code. ==Store Queues== These come in handy when flushing vertices to the graphics hardware or to memory. Basically all they are for is batching up 32 bytes of data and flushing it to some location. The store queues can be used to write to main memory but they bypass the cache thus cache synchronization may become an issue. There are some benefits when using the store queues, among them there are two which I think are worth mentioning. First there are two of them each 32 bytes in size and both operate independently, i.e. you can instruct one store queue to flush its contents and write to the other at the same time without stalling the program code. Then there is another nice feature which I call "data cloning". Sometimes you need to clone data for whatever reason. For one normal store and one cloning operation this implies two reads and two writes per element. With appropriate pointer mapping setup you can reduce this to one read and two writes which will boost the performance of your code. The trick is easy to do. All you have to do is telling a store queue to flush with two different addresses. The store queue number is indicated by bit 6 of the flushing address and the other upper bits are the raw address where the store queue content is flushed to. However, each flush instruction will stall the code until the concerned store queue has finished a previous flush operation. So it's best to do something else between two flush instructions. Notice also that the store queues can be used in conjunction with the MMU for mapping the store queue address space to different pieces of hardware which eliminates the need to set up the QARC0 / QARC1 registers. ==Optimizing TnL Loops== This is probably one of the most frequent optimization topics. Always remember the 20-80 rule: 80 percent of the time is spent in 20 percent of the code. Thus first of all identify your bottle necks. For the most cases this will be the graphics routines, or more precicely the transform and lighting part of the graphics routines, since on Dreamcast this stuff is done by the CPU. When doing "complex" transformation and lighting you may get very large loops that do a lot of operations per vertex. Of course it's best to avoid any operations in the first place (culling) but eventually you will have to compute the lighting intensities for 3 light sources, compute the bumpmapping parameters, apply 8 skinning matrices or whatever you are going to do with one vertex. Let's take a simple example which is supposed to apply diffuse and specular lighting to a vertex, transforming the vertex and storing it in a buffer. This may look as follows: <syntaxhighlight lang="c"> do { fetch vertex apply diffuse lighting ((N * L) * material diffuse color * light color) apply specular lighting (pow ((N * H), material shininess) * material specular color * light color) clamp and pack the lighting result to packed 32 bit ARGB apply transformation (matrix) * (x,y,z,1) apply perspective divide (1/w) write back vertex } while (-- count); </syntaxhighlight> Now add a few more things and you will get quite a big loop and you will run out of FPU registers for sure. Additionally this code is subject to bad pipelining since most of the operatations depend on the results of previous operations. So there are a few things we better do in a different way. Normally each vertex does not depend on adjacent vertices in the buffer. The operations applied are the same for each vertex. If we had a lot of CPU cores as the Cell Processor will we could do some parallel processing, but we don't. Still there is a way to speed things up by processing two vertices at a time, but this will work only if there are enough FPU registers left to hold at least some parts of a second vertex. What we do is simply breaking up the loop in independent and simple steps: *apply diffuse lighting *apply specular lighting *clamp and pack lighting result *apply transformation and perspective divide Thus we'll get something like... <syntaxhighlight lang="c"> do { fetch vertex parts apply diffuse lighting store temporary results } while (-- count); do { fetch vertex parts apply specular lighting store temporary results } while (-- count); do { fetch temporary results clamp and pack lighting result store packed values } while (-- count); do { fetch vertex parts apply transformation apply perspective divide store results } while (-- count); </syntaxhighlight> Now we have small and simple loops that can be pipelined much better since there are more spare registers left. Also the loops can be applied in any order and in any combination making the code more flexible. For instance, if you don't need specular lighting then just don't call the specular lighting loop, that's it. The trick now is to run the small loops not over the whole buffer at once but over smaller blocks of the buffer. This way the currently processed vertices will be kept in the cache for each of the many loop iterations. As to my experience a block size of 32 vertices gives the best performance. Decreasing the value may introduce loop startup or function call overhead. Increasing the value may also increase cache misses. It's the same as with network packet sizes: you have to try a little bit to find the best value. 1d5f1ddcb9ffea2c49cee3b0592af4e55dcc1cf7 Playing SFX 0 277 3227 1018 2023-11-13T15:04:28Z BBHoodsta 2 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on playing sound effects on the Sega Dreamcast. The Sega Dreamcast has '''2MB''' of sound RAM and supports '''64 channels''' which gives you the ability to play many sound effects at once (1 sound effect per channel). A sound effect can be either stereo or mono, and must either be '''8/16-bit uncompressed PCM''' samples or '''4-bit Yamaha ADPCM'''. All sounds played in this manner must be at most '''65534''' samples in length. That is samples, not bytes (samples != bytes). Each sound effect has a sample rate. The standard sample rate of a sound is '''44.1 kHz''' (44100 Hz/sec => 44100 samples/sec). So mathematically you're getting 65534/44100 => '''1.486''' secs of sound per sound effect using the standard sample rate. You can lesson the sample rate of your sound to get a longer sound effect but audio quality will be affected. This guide does not cover playing music from CD or RAM, look at [[Streaming audio]] instead. = API = The KOS [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found within [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_sfxmgr.c <code>'''snd_sfxmgr.c'''</code>]. == Initializing Sound System == <syntaxhighlight lang="c">int snd_init()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 <code>'''snd_init()'''</code>] function initializes the sound system. It is usually called at the beginning of your program. You can't play sound effects before calling this function. == Load Sound Effect == <syntaxhighlight lang="c">sfxhnd_t snd_sfx_load(const char* fn)</syntaxhighlight> After initializing the sound system you can start loading sound effects. The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#ac5de88124b6cd04af8e4737b05c4b482 <code>'''snd_sfx_load()'''</code>] function loads a sound effect from a WAV file and returns a handle to it. The sound effect can be either stereo or mono, and must either be 16-bit uncompressed PCM samples or 4-bit Yamaha ADPCM. Keep in mind that you have less than 2MB of sound RAM to work with. == Play Sound Effect == <syntaxhighlight lang="c">int snd_sfx_play(sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a4fb2bd23ff153c8bd1493a6417ff718f <code>'''snd_sfx_play()'''</code>] function plays a loaded sound effect with the specified volume (for both stereo or mono) and panning values (for mono sounds only). Behind the scenes this picks a channel that is not currently in use and plays it on that channel. This is important because no two sound effects can play on the same channel at the same time. * The volume to play at (between 0 and 255). * The panning value of the '''mono''' sound effect. 0 is all the way to the left, 128 is center, 255 is all the way to the right. <syntaxhighlight lang="c">int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a43534fc7fa4676be555482dbe7926f54 <code>'''snd_sfx_play_chn()'''</code>] function works similar to snd_sfx_play(), but allows you to specify the channel to play on. * The channel value can be between 0 and 63. == Stop Sound Effects == <syntaxhighlight lang="c">void snd_sfx_stop(int chn)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a26d2c1e14131496e2ba920c5967750c7 <code>'''snd_sfx_stop()'''</code>] function stops the specified channel of sound from playing. <syntaxhighlight lang="c">void snd_sfx_stop_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a6874523117d3aae46ab49567ffe33b5e <code>'''snd_sfx_stop_all()'''</code>] function stops all channels currently allocated to sound effects from playing. == Unload Sound Effects == <syntaxhighlight lang="c">void snd_sfx_unload(sfxhnd_t idx)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#afaaacbd4c0d4ae869f9a250f61417893 <code>'''snd_sfx_unload()'''</code>] function unloads a previously loaded sound effect, and frees the memory associated with it. <syntaxhighlight lang="c">void snd_sfx_unload_all()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sfxmgr_8h.html#a706323762562d9b6cf3a57870f35d14e <code>'''snd_sfx_unload_all()'''</code>] function unloads all previously loaded sound effect, and frees the memory associated with them. == Shutdown Sound System == <syntaxhighlight lang="c">void snd_shutdown()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#aaaa1b0da74e9d8e2615c6a5aa9a160b1 <code>'''snd_shutdown()'''</code>] function shuts down the sound system and frees all allocated memory. = Code Example = The following example demonstrates how to play sound effects on their own channel (using <code>'''snd_sfx_play()'''</code>) and on the same channel(using <code>'''snd_sfx_play_chn()'''</code>). By playing the sound effects on their own channel (pressing A,B,X,Y), you will notice that the sound effects can overlap each other; while playing sound effects on the same channel (with the d-pad), you will only hear one sound effect at a time. Another thing to point out is that all of the beep WAV files referenced here are MONO so I also pan the sound with hard coded values (LEFT, CENTER, RIGHT). You can also adjust the volume of all the sound effects using the left and right triggers of the controller. Error handling is non-existent in this example. You'll want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/SFX Github]'''. '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="22, 25-28, 42, 45, 48, 51, 56, 59, 62, 65, 93-96, 98, 100"> #include <kos.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t volume = 128; int volume_changed = 1; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system snd_init(); // Load wav files found in romdisk sfxhnd_t beep1 = snd_sfx_load("/rd/beep-1.wav"); sfxhnd_t beep2 = snd_sfx_load("/rd/beep-2.wav"); sfxhnd_t beep3 = snd_sfx_load("/rd/beep-3.wav"); sfxhnd_t beep4 = snd_sfx_load("/rd/beep-4.wav"); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play sounds on different channels if(button_pressed(current_buttons, changed_buttons, CONT_A)) { snd_sfx_play(beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_B)) { snd_sfx_play(beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(beep4, volume, CENTER); } // Play sounds on same channel if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { snd_sfx_play_chn(0, beep1, volume, CENTER); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_RIGHT)) { snd_sfx_play_chn(0, beep2, volume, RIGHT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_LEFT)) { snd_sfx_play_chn(0, beep3, volume, LEFT); } if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { snd_sfx_play_chn(0, beep4, volume, CENTER); } // Adjust Volume if(cond->ltrig > 0) { volume_changed = 1; if(volume < 254) volume++; } if(cond->rtrig > 0) { volume_changed = 1; if(volume > 0) volume--; } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; if(volume_changed) { volume_changed = 0; draw_instructions(volume); } } // Unload all sound effects from sound RAM snd_sfx_unload(beep1); snd_sfx_unload(beep2); snd_sfx_unload(beep3); snd_sfx_unload(beep4); // OR // snd_sfx_unload_all(); snd_shutdown(); return 0; } static void draw_instructions(uint8_t volume) { int x = 20, y = 20+24; int color = 1; char current_volume_str[32]; memset(current_volume_str, 0, 32); snprintf(current_volume_str, 32, "Current Volume: %3i", volume); bfont_draw_str(vram_s + y*640+x, 640, color, "Press A,B,X,Y to play beeps on separate channels"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press UP,DOWN,LEFT,RIGHT on D-Pad to play beeps"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "on the same channel"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press L-Trigger/R-Trigger to +/- volume"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, current_volume_str); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 101e34794679df90bf3c8533db78c05dfcd2cf42 Streaming audio 0 283 3228 993 2023-11-13T15:07:17Z BBHoodsta 2 wikitext text/x-wiki Author: Andress Barajas = Introduction = This guide will focus solely on streaming sound on the Sega Dreamcast. Unlike sound effects, sound that is streamed is '''NOT''' uploaded all-at-once to the Dreamcast AICA RAM. Rather a small buffer of MAX 65536 bytes(per channel) is allocated that we constantly refill while sound is being played. Streamed sound can be either mono or stereo and can be '''16-bit uncompressed PCM''', '''8-bit PCM''' or '''4-bit Yamaha ADPCM'''. The max amount of streams that can exist at once is '''4'''. This hard limit does not apply to sound effects. You can have 4 sound streams playing at once and have many sound effects depending on how much AICA RAM is left. The libraries in [https://github.com/KallistiOS/kos-ports kos-ports] that most people use to stream sound are '''libmp3''', '''libogg''', and '''libtremor'''. These sound libraries take care of all the nitty-gritty stuff covered in the API section. '''So much so that you can skip the API section and go straight to the code example section to get started'''. The approach these sound libraries use to stream sound is to create and run a detached thread in the background that constantly polls the AICA, asking it how much sound data it wants so it can keep streaming. This polling executes a callback where we then decode sound data into a buffer and return that buffer to the AICA to read from. This process continues until we reach the end of the sound file that we are playing. = API = The KOS [http://cadcdev.sourceforge.net/docs/kos-current/stream_8h.html# reference manual] for this API contains more detail on each function and also has more functions not listed here. The source code for most of these methods can be found within [https://github.com/KallistiOS/KallistiOS/blob/master/kernel/arch/dreamcast/sound/snd_stream.c <code>'''snd_stream.c'''</code>]. == Initialize Sound System == <syntaxhighlight lang="c">int snd_stream_init()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a894f8e31f38fcf3d85c6f3ba31f270ce <code>'''snd_stream_init()'''</code>] function initializes the sound system for streaming by allocating some internal stream buffers. It is usually called at the beginning of your program. You can't stream sound before calling this function. This will implicitly call [http://gamedev.allusion.net/docs/kos-2.0.0/sound_8h.html#a1a108c6193ac7ab667c68ab412f04f66 <code>'''snd_init()'''</code>], so you can also play sound effects. == Stream Callback == <syntaxhighlight lang="c">typedef void*(* snd_stream_callback_t)(snd_stream_hnd_t hnd, int smp_req, int *smp_recv)</syntaxhighlight> Functions for providing stream data will be of this type, and can be registered with '''snd_stream_alloc()''' or '''snd_stream_set_callback()'''. * '''hnd''' The stream handle being referred to. * '''smp_req''' The number of samples requested. * '''smp_recv''' Used to return the number of samples available. Returns: A pointer to the buffer of samples. If stereo, the samples should be interleaved. == Allocate Sound Stream == <syntaxhighlight lang="c">snd_stream_hnd_t snd_stream_alloc(snd_stream_callback_t callback, int bufsize)</syntaxhighlight> After initializing the sound system you can start allocating sound streams. The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a8d861495b80a40f14bd09d34d264db55 <code>'''snd_stream_alloc()'''</code>] function allocates a stream and sets its parameters. The maximum number of streams that can be allocated at one time is 4 ([http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ac6a4dd8ba64ce0598beec50ba5c04cca <code>'''SND_STREAM_MAX '''</code>]). This function returns a stream handler that will be used to play/stop streams among other things. * '''callback''' is the function where we decode and send sound data to AICA. * '''bufsize''' is the size of the streaming buffer we want to create in AICA RAM. The maximum size of the buffer we can set is [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a082956718695c49f9bb288db467ef019 <code>'''SND_STREAM_BUFFER_MAX'''</code>] (65536 bytes...per channel so 65536*2 bytes internally to support stereo) . The smaller the buffer size means the sound buffer is filled up faster, which means the sound begins to play quicker. This however means we are decoding many small portions of sound data at a time rather than in bigger chunks. This causes overhead because we are calling the callback function many more times by doing that. I will explain stream queuing which gives us the benefit of both using the max buffer size and having sound playing instantaneously when you start streaming. == Start Stream == <syntaxhighlight lang="c">void snd_stream_start(snd_stream_hnd_t hnd, uint32 freq, int stereo)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a0c0031c395dab0ce8fdc6878ecd9875d <code>'''snd_stream_start()'''</code>] function starts a stream. This function starts processing the given stream, prefilling the buffers as necessary. In queueing mode, this will not start playback. * '''hnd''' The stream to start. * '''freq''' is the frequency of the audio data. Most of the time this is gonna be 44.1Hz. * '''stereo''' is a boolean saying whether the sound data we are streaming is '''1'''-Stereo or '''0'''-Mono == Poll Stream == <syntaxhighlight lang="c">int snd_stream_poll(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a20ac8845b717ca18ddd5dd5a5df676a2 <code>'''snd_stream_poll()'''</code>] function polls the specified stream to load more data if necessary. If more data is requested, the callback function set in [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a8d861495b80a40f14bd09d34d264db55 <code>'''snd_stream_alloc()'''</code>] is executed. * '''hnd''' The stream to poll. == Stop Stream == <syntaxhighlight lang="c"> void snd_stream_stop(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a30aff86794b37e03ae55c2b214962d14 <code>'''snd_stream_stop()'''</code>] function stops a stream, stopping any sound playing from it. This will happen immediately, regardless of whether queueing is enabled or not. * '''hnd''' The stream to stop. == Stream Volume == <syntaxhighlight lang="c">void snd_stream_volume(snd_stream_hnd_t hnd, int vol)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a609a1f999996a6aec8b5f314fe8ad2b5 <code>'''snd_stream_volume()'''</code>] function sets the volume of the specified stream. * '''hnd''' The stream to set volume on. * '''vol''' The volume to set. Valid values are 0-255. == Set Stream Callback == <syntaxhighlight lang="c">void snd_stream_set_callback(snd_stream_hnd_t hnd, snd_stream_callback_t callback)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a895c5ae7c752e1cc0ce3c5d5be17fac3 <code>'''snd_stream_set_callback()'''</code>] function updates the get data callback function for a given stream, overwriting any old callback that may have been in place. * '''hnd''' The stream handle for the callback. * '''callback''' A pointer to the callback function. == Destroy Stream == <syntaxhighlight lang="c">void snd_stream_destroy(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ab53343e65d805c051fad11c5d1c0f887 <code>'''snd_stream_destroy()'''</code>] function destroys a previously created stream, freeing all memory associated with it. * '''hnd''' The stream to clean up. == Shutdown Stream System == <syntaxhighlight lang="c">void snd_stream_shutdown()</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a6c818794fe63f75ce0590ba00dec8255 <code>'''snd_stream_shutdown()'''</code>] function shuts down the stream system and frees the memory associated with it. This does not call snd_shutdown(). == Stream Queuing == The stream queuing system allows you to setup a stream to be played, prefilling the buffers, without actually starting the stream. This can be useful if you want to setup a stream long before actually using it. Since the buffers are pre-filled with sound data, playback of the stream is immediate. Normally the route to start playback of a stream is to first allocate a stream using '''snd_stream_alloc()''' and then use '''snd_stream_start()'''. What '''snd_stream_start()''' does internally is that it decodes sound data until the buffer (which you set the size of in '''snd_stream_alloc()''') is full and then sound starts playing. This process isn't instant because decoding the sound data and moving it to the AICA takes time. Normally this is not an issue but if you want to sync the playback of the stream with a button press you will get a delay: <syntaxhighlight lang="c">if(A_BUTTON_IS_PRESSED)) { snd_stream_start(hnd, freq, stereo); }</syntaxhighlight> What you should do instead after allocating a stream using '''snd_stream_alloc()''' is to call '''snd_stream_queue_enable()''' and then '''snd_stream_start()'''. Because we enabled queuing of the stream, the stream will not start playback when we call '''snd_stream_start()'''. It just pre-fills the buffers for us. Then in your control input loop: <syntaxhighlight lang="c">if(A_BUTTON_IS_PRESSED)) { snd_stream_queue_go(hnd); }</syntaxhighlight> === Enable Stream Queue === <syntaxhighlight lang="c">void snd_stream_queue_enable(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#afabae350915f2565c372427f9618e2a7 <code>'''snd_stream_queue_enable()'''</code>] function enables queueing on the specified stream. This will make it so that you must call snd_stream_queue_go() to actually start the stream, after scheduling the start. This is useful for getting something ready but not firing it right away. * '''hnd''' The stream to enable queueing on. === Disable Stream Queue === <syntaxhighlight lang="c">void snd_stream_queue_disable(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a32408db8b9981584904b854192a42aac <code>'''snd_stream_queue_disable()'''</code>] function disables queueing on the specified stream. This does not imply that a previously queued start on the stream will be fired if queueing was enabled before. * '''hnd''' The stream to disable queueing on. === Start Queued Stream === <syntaxhighlight lang="c">void snd_stream_queue_go(snd_stream_hnd_t hnd)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ad639910648dad0c8bf2ec2a2947d445d <code>'''snd_stream_queue_go()'''</code>] function makes the stream start once a start request has been queued, if queueing mode is enabled on the stream. * '''hnd''' The stream to start the queue on. == Stream Filtering == This allows you to apply filters to the decoded sound data that is returned by the callback you set in '''snd_stream_alloc()'''. In order to filter the sound you need to create a function with the filter callback(shown below) and adding it to a stream using '''snd_stream_filter_add()'''. This can create cool dynamic sound manipulation. Manipulating sound data is out of scope of this tutorial and requires you to study DSP(Digital Signal Processing). Keep in mind that you will only be manipulating small portions of sound data at a time. === Filter Callback === <syntaxhighlight lang="c">typedef void(* snd_stream_filter_t)(snd_stream_hnd_t hnd, void *obj, int hz, int channels, void **buffer, int *samplecnt) </syntaxhighlight> Functions providing filters over the stream data will be of this type, and can be set with '''snd_stream_filter_add()'''. * '''hnd''' The stream being referred to. * '''obj''' Filter user data. * '''hz''' The frequency of the sound data. * '''channels''' The number of channels in the sound data. * '''buffer''' A pointer to the buffer to process. This is before any stereo separation is done. Can be changed by the filter, if appropriate. * '''samplecnt''' A pointer to the number of samples/bytes. This can be modified by the filter, if appropriate. === Add Stream Filter === <syntaxhighlight lang="c">void snd_stream_filter_add(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, void* obj)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#ab8002470c114f347ea6b9f1e2fe4e299 <code>'''snd_stream_filter_add()'''</code>] function adds a filter to the specified stream. The filter will be called on each block of data input to the stream from then forward. * '''hnd''' The stream to add the filter to. * '''filtfunc''' A pointer to the filter function. * '''obj''' Filter function user data. === Remove Stream Filter === <syntaxhighlight lang="c">void snd_stream_filter_remove(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, void* obj)</syntaxhighlight> The [http://gamedev.allusion.net/docs/kos-2.0.0/stream_8h.html#a627b9debe59409f085b462f551f17cb8 <code>'''snd_stream_filter_remove()'''</code>] function removes a filter that was previously added to the specified stream. * '''hnd''' The stream to remove the filter from. * '''filtfunc''' A pointer to the filter function to remove. * '''obj''' The filter function's user data. Must be the same as what was passed as obj to '''snd_stream_filter_add()'''. = Code Example = The following code example, which is mostly devoid of the API functions listed above, demonstrates how to stream sound using the libtremor library. The libtremor is a playback library used to play '''.ogg''' sound files. liboggvorbisplay is another library that plays '''.ogg''' files but uses float arithmetic and consumes more memory. Stick with libtremor. I also recommend that you avoid using libmp3 as a playback library if you want to keep your project closed source since its licensed under '''GNU General Public License version 2''' and requires your project to be open source. This code example requires that you have libtremor installed. In your kos-ports directory you will find libtremor. Using your terminal, navigate to that folder and execute: <code>make install clean</code> Error handling is non-existent in this example. You'll want to check if the sound effects are loaded correctly and that you have a controller plugged in when running this demo. You can find all the code and resources of this example on '''[https://github.com/andressbarajas/dreamcastwiki/tree/master/Audio/Stream/Streaming Github]'''. Three versions of this example exist for each playback library(libtremor, libmp3, and libwav). '''NOTE: This code sample may not work in Sega Dreamcast emulators.''' <syntaxhighlight lang="c" line="line" highlight="32, 33, 39, 40, 65, 67, 68,74, 95, 97, 106-108"> #include <kos.h> #include <oggvorbis/sndoggvorbis.h> #define LEFT 0 #define CENTER 128 #define RIGHT 255 #define LOOP 1 #define SHAKER_VOL 200 #define INITIAL_CRY 128 #define LOUDEST_CRY 240 extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); static void draw_instructions(uint8_t volume); static cont_state_t* get_cont_state(); static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button); int main(int argc, char **argv) { uint8_t baby_volume = INITIAL_CRY; uint8_t shake_volume = SHAKER_VOL; uint64_t start_time = timer_ms_gettime64(); uint64_t end_time = start_time; cont_state_t* cond; vid_set_mode(DM_640x480, PM_RGB555); // Initialize sound system and OGG snd_stream_init(); sndoggvorbis_init(); // Load wav files found in romdisk sfxhnd_t shake1 = snd_sfx_load("/rd/shake-1.wav"); sfxhnd_t shake2 = snd_sfx_load("/rd/shake-2.wav"); sndoggvorbis_volume(baby_volume); // Can put volume before starting sndoggvorbis_start("/rd/baby-whining-01.ogg", LOOP); unsigned int current_buttons = 0; unsigned int changed_buttons = 0; unsigned int previous_buttons = 0; for(;;) { cond = get_cont_state(); current_buttons = cond->buttons; changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; // Play rattle sounds to calm the baby if(button_pressed(current_buttons, changed_buttons, CONT_X)) { snd_sfx_play(shake1, shake_volume, LEFT); if(baby_volume > 40) baby_volume -= 10; } if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { snd_sfx_play(shake2, shake_volume, RIGHT); if(baby_volume > 40) baby_volume -= 10; } // Wake the baby if(button_pressed(current_buttons, changed_buttons, CONT_A)) { if(!sndoggvorbis_isplaying()) { baby_volume = INITIAL_CRY; sndoggvorbis_volume(baby_volume); sndoggvorbis_start("/rd/baby-whining-01.ogg", LOOP); } } // Force the baby to sleep if(button_pressed(current_buttons, changed_buttons, CONT_B)) { baby_volume = 0; sndoggvorbis_stop(); } // Exit Program if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; // Adjust Volume with time end_time = timer_ms_gettime64(); // Increase baby volume by 15 every second (Max LOUDEST_CRY) if((end_time - start_time) >= 1000) { baby_volume += 15; start_time = end_time; } if(baby_volume > LOUDEST_CRY) { baby_volume = LOUDEST_CRY; } // If baby volume goes <= 40, put baby to sleep if(baby_volume <= 40) { baby_volume = 0; sndoggvorbis_stop(); } else { sndoggvorbis_volume(baby_volume); } draw_instructions(baby_volume); } // Unload all sound effects from sound RAM snd_sfx_unload_all(); sndoggvorbis_stop(); sndoggvorbis_shutdown(); snd_stream_shutdown(); return 0; } static void draw_instructions(uint8_t baby_volume) { int x = 20, y = 20+24; int color = 1; char baby_status[50]; memset(baby_status, 0, 50); if(baby_volume == 0) { snprintf(baby_status, 50, "%-50s", "Baby is asleep!!! Finally..."); } else if(baby_volume > 40 && baby_volume <= 90) { snprintf(baby_status, 50, "%-50s", "Baby is almost asleep. Keep rattling!!"); } else if(baby_volume > 90 && baby_volume <= 180) { snprintf(baby_status, 50, "%-50s", "You can do better than that!"); } else if(baby_volume > 180 && baby_volume <= LOUDEST_CRY) { snprintf(baby_status, 50, "%-50s", "Are you even rattling!?!?!"); } bfont_draw_str(vram_s + y*640+x, 640, color, "Press X and/or Y to play rattle sounds to calm"); y += 24; bfont_draw_str(vram_s + y*640+x, 640, color, "down the baby so it can go to sleep"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press A to wake the baby up"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press B to force baby asleep"); y += 48; bfont_draw_str(vram_s + y*640+x, 640, color, "Press Start to exit program"); y += 72; bfont_draw_str(vram_s + y*640+x, 640, color, baby_status); } static cont_state_t* get_cont_state() { maple_device_t* cont; cont_state_t* state; cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(cont) { state = (cont_state_t*)maple_dev_status(cont); return state; } return NULL; } static int button_pressed(unsigned int current_buttons, unsigned int changed_buttons, unsigned int button) { if (changed_buttons & button) { if (current_buttons & button) return 1; } return 0; } </syntaxhighlight> 4de59163d6b7d552f2cc72c61364b4024aecba50 Coder's cable 0 90 3229 3187 2023-11-21T13:44:33Z Tchan 166 added darc's cable info, and cleaned up formatting wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == Buy a pre-made cable == * eg: Contact '''darc''' on the [https://discord.com/invite/TRx94EV Simulant Discord] for a pre-made CP2102N-based cable * eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) == Build your own cable == * DC serial connector: ** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 16 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} * select a usb-to-serial chip/cable (+- 10 USD) ** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: *** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. *** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] *** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] *** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** eg [https://github.com/cepawiel/dc-serial Colton's custom PCB] - Kicad files to order a custom PCB with a CP2102N, to be soldered to the serial connector of a DC SD Adapter V2 ** FDTI's '''FT232R'''-like chips: *** '''good until 781250''', does not support 1562500. *** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. **** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... * connect the following pins (cfr [[Serial_interface]]): ** GND <-> GND ** TXD <-> RXD ** RXD <-> TXD ** RTS <-> CTS ** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') *** Disclaimer for Linux only: needs dc-tool-ser (host) changes from 4 september 2023 to select custom baudrates *** Disclaimer for MacOS only: custom baudrates are not supported yet ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 22b937506ccf7ff8d057f8d75eab9836bc98205f 3230 3229 2023-11-21T14:11:24Z Tchan 166 price indication adaptations wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == Buy a pre-made cable == * eg: Contact '''darc''' on the [https://discord.com/invite/TRx94EV Simulant Discord] for a pre-made CP2102N-based cable * eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) == Build your own cable == * DC serial connector: ** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 20 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} * select a usb-to-serial chip/cable (+- 15 USD) ** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: *** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. *** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] *** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] *** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** eg [https://github.com/cepawiel/dc-serial Colton's custom PCB] - Kicad files to order a custom PCB with a CP2102N, to be soldered to the serial connector of a DC SD Adapter V2 ** FDTI's '''FT232R'''-like chips: *** '''good until 781250''', does not support 1562500. *** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. **** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... * connect the following pins (cfr [[Serial_interface]]): ** GND <-> GND ** TXD <-> RXD ** RXD <-> TXD ** RTS <-> CTS ** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') *** Disclaimer for Linux only: needs dc-tool-ser (host) changes from 4 september 2023 to select custom baudrates *** Disclaimer for MacOS only: custom baudrates are not supported yet ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 68a13c7f2464c61677bfbbda05886e54dfe5fe0b 3231 3230 2023-11-21T18:47:10Z Darc 1 /* Buy a pre-made cable */ wikitext text/x-wiki The '''coder's cable''' is the name given to the serial-based cable some developers use to test and debug code during development. Originally, cables were connected to host devices via serial, but modern cable designs incorporate a USB controller instead. Coder's cables can also be used for other purpose's besides development, such as transferring VMU data back to a PC or dumping GD-ROMs (although quite slowly). == Buy a pre-made cable == * eg: Contact '''darc''' on the [https://dcemulation.org/phpBB/memberlist.php?mode=viewprofile&u=5284 DCEmulation Forums] or [https://discord.com/invite/TRx94EV Simulant Discord] for a pre-made CP2102N-based cable * eg: [https://www.retroonyx.com/product-page/dreamcast-usb-coders-cable retroonyx cable], FTDI-based cable. * (only mentioned for historical purposes - not sold anymore since long - "Lik-Sang coder's cable" - max speed of 781250) == Build your own cable == * DC serial connector: ** best connector today is the one used by the [https://www.ebay.com/sch/i.html?_nkw=DC+SD+Adapter+V2 DC SD Adapter V2] (+- 20 USD) {| | [[File:DC SD Adapter V2.jpg|thumb|alt=DC SD Adapter V2|DC SD Adapter V2]] |} * select a usb-to-serial chip/cable (+- 15 USD) ** [https://www.silabs.com/interface/usb-bridges/usbxpress Silicon Labs '''CP2102N''']: *** Supports 1600000, which is a 2,4% baudrate mismatch with the Dreamcast, which seems acceptable for high speeds. Best chip that can be recommended today. Tests give speeds of 170-190 kByte/sec and more thanks to compression. *** eg [https://www.adafruit.com/product/5335 Adafruit CP2102N Friend (USB-C)] *** eg [https://www.silabs.com/development-tools/interface/cp2102n-mini-development-kit?tab=overview Silicon Labs CP2102N-MINIEK (mini USB)] *** eg [https://www.amazon.co.uk/DSD-TECH-SH-U09BL-Serial-CP2102N/dp/B08JLRP6YV DSD TECH SH-U09BL USB to TTL Serial Cable with CP2102N Chip] *** eg [https://github.com/cepawiel/dc-serial Colton's custom PCB] - Kicad files to order a custom PCB with a CP2102N, to be soldered to the serial connector of a DC SD Adapter V2 ** FDTI's '''FT232R'''-like chips: *** '''good until 781250''', does not support 1562500. *** 500000 and 1500000 will not work with all chips/on all pc, because of a 4% baud rate mismatch with the baudrates of the Dreamcast. **** Even if you're lucky, you won't really get 1500000-worthy speeds - more probably around 130-150 kByte/sec... * connect the following pins (cfr [[Serial_interface]]): ** GND <-> GND ** TXD <-> RXD ** RXD <-> TXD ** RTS <-> CTS ** CTS <-> RTS == Software to use == [[Dcload-serial]] == Supported Baud Rates == '''Not all common baudrates work''', so the recommendations are: * '''up until 115200''', you can use the common baudrates: 9600, 19200, 38400, 57600, 115200 ** if 115200 does not work, you can add the "-e" speedhack option * '''higher baudrates''': ** try first with the '''dreamcast-specific baudrates''' (223214, 260416, 312500, 390625, '''520833, 781250, 1562500''') *** Disclaimer for Linux only: needs dc-tool-ser (host) changes from 4 september 2023 to select custom baudrates *** Disclaimer for MacOS only: custom baudrates are not supported yet ** '''230400''': use the -e speedhack option if you absolutely need 230400 at pc-side, but the DC will use 223214 or 260416 anyways. ** '''500000 and 1500000''': you can try, but that will not work on all pc (the mismatch with the baudrate of the Dreamcast is sometimes too big (4%)) {{DCWiki:Stub}} 450977591327a323fe3d45136b1864bbd915726e Dream Web Console 0 1403 3232 2023-11-25T21:56:33Z Darc 1 Created page with "Dream Web Console!" wikitext text/x-wiki Dream Web Console! 5014ea9cd3049760c9117227a4161e51f5f352a1 Dwc 0 1404 3233 2023-11-25T21:57:08Z Darc 1 Redirected page to [[Dream Web Console]] wikitext text/x-wiki #REDIRECT [[Dream Web Console]] 44c47a497ccf6f40851a521e1c353927fac06a59 File:Performance VMU.jpg 6 1405 3236 2023-12-05T02:35:21Z GyroVorbis 13 wikitext text/x-wiki Performance 3rd Party VMU 4c89b5a01c1c20d667d8332072d3f56d713479d2 Performance 3rd Party VMU 0 1406 3237 2023-12-05T02:47:49Z GyroVorbis 13 Created page with "[[File:Performance VMU.jpg|thumb|Performance 3rd Party VMU]] Despite popular belief, there is actually one known third-party Visual Memory Unit: the ultra-rare "Performance" VMU. While it lacks the full standalone GAME mode featured in the first-party VMUs, preventing it from playing minigames, it does provide equivalent functionality while plugged into the controller and even has a builtin firmware offering several features when used in standalone mode. === Features ==..." wikitext text/x-wiki [[File:Performance VMU.jpg|thumb|Performance 3rd Party VMU]] Despite popular belief, there is actually one known third-party Visual Memory Unit: the ultra-rare "Performance" VMU. While it lacks the full standalone GAME mode featured in the first-party VMUs, preventing it from playing minigames, it does provide equivalent functionality while plugged into the controller and even has a builtin firmware offering several features when used in standalone mode. === Features === Maple Functionality (when connected to the controller): * LCD Display Screen * Buzzer Tone Generation * 8-bit FAT Filesystem Unknown Support: * Can VMU Buttons be accessed while plugged into the controller as with first-party VMUs? === Packaging === === Hardware === === Bugs/Extras === 17d5123fb5a75799616af2692c18f2f056b1ec4a 3245 3237 2023-12-05T03:01:24Z GyroVorbis 13 wikitext text/x-wiki [[File:Performance VMU.jpg|thumb|Performance 3rd Party VMU]] Despite popular belief, there is actually one known third-party Visual Memory Unit: the ultra-rare "Performance" VMU. While it lacks the full standalone GAME mode featured in the first-party VMUs, preventing it from playing minigames, it does provide equivalent functionality while plugged into the controller and even has a builtin firmware offering several features when used in standalone mode. === Features === Maple Functionality (when connected to the controller): * LCD Display Screen * Buzzer Tone Generation * 8-bit FAT Filesystem Standalone Functionality (when battery-powered): * Calendar Unknown Support: * Can VMU Buttons be accessed while plugged into the controller as with first-party VMUs? === Packaging === [[File:Front Box of Performance VMU.jpg|thumb|left|Front Packaging of the Performance VMU]] [[File:Performance VMU Box Rear.jpg|thumb|center|Front Packaging of the Performance VMU]] === Hardware === [[File:Performance VMU Insides.png|thumb|center|Disassembled Performance VMU]] === Bugs/Extras === [[File:Performance VMU Calendar.jpg|thumb|center|Performance VMU Calendar]] eb480a91dba6d3766f75683cb3cb4eef4b8bd443 File:Performance VMU Box Rear.jpg 6 1407 3238 2023-12-05T02:49:33Z GyroVorbis 13 wikitext text/x-wiki Front Packaging of the Performance VMU 26c6a184447639f55ee82193dd2c321f34acf221 3240 3238 2023-12-05T02:53:26Z GyroVorbis 13 GyroVorbis moved page [[File:Performance VMU Box Front.jpg]] to [[File:Performance VMU Box Rear.jpg]]: Misnamed wikitext text/x-wiki Front Packaging of the Performance VMU 26c6a184447639f55ee82193dd2c321f34acf221 3242 3240 2023-12-05T02:53:42Z GyroVorbis 13 wikitext text/x-wiki Rear Packaging of the Performance VMU b3e24c09f04ea08f8c3cbb8bac14a4fdf6a13d55 File:Front Box of Performance VMU.jpg 6 1408 3239 2023-12-05T02:51:46Z GyroVorbis 13 wikitext text/x-wiki Front Packaging of the Performance VMU 26c6a184447639f55ee82193dd2c321f34acf221 File:Performance VMU Box Front.jpg 6 1409 3241 2023-12-05T02:53:26Z GyroVorbis 13 GyroVorbis moved page [[File:Performance VMU Box Front.jpg]] to [[File:Performance VMU Box Rear.jpg]]: Misnamed wikitext text/x-wiki #REDIRECT [[File:Performance VMU Box Rear.jpg]] bc9fcc60e67ffe28aad1c8828969044253c384a5 File:Performance VMU Insides.png 6 1410 3243 2023-12-05T02:59:06Z GyroVorbis 13 wikitext text/x-wiki Disassembled Performance VMU f9d263900f77c3c638da26b6820b1b1916c55e0c File:Performance VMU Calendar.jpg 6 1411 3244 2023-12-05T03:00:54Z GyroVorbis 13 wikitext text/x-wiki Performance VMU Calendar a0bc1778758600a5d8f3cad2b3a6ec3ce6c131c2 OpenBORManual 0 1314 3246 2578 2023-12-06T21:00:15Z Darc 1 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. '''Last update on 2020.12.16 - by O Ilusionista''' * Native Functions: added @cmd projectile usage example =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it's 200 and for bikers it's 300. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For 'subtype biker' enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to "K'" (Yes, with an apostrophe ') * If the rider is only loaded with 'know' in models.txt, you should add 'load {name}' in this biker text to ensure that the 'rider' will fall off. ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However 'background' sets the bottommost layer while 'bglayer' sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don't use it on images that won't benefit from it. And don't use it for 'background' too since it's the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don't use it for background too. * {watermode} determines water effect. Currently there are 3 modes. **0 = No water effect for this bglayer **1 = Water effect for this bglayer is on **3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have **0 = No effect (default) **1 = Perspective & tile **2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {path}''' * {path} points to a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, 'palette' command (see below) won't work * frontpanels display in the order they are declared and repeat when they run out. You don't need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio which can't be changed. If you don't like it, use 'fglayer' below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path}<span style="color: gray;> {z} </span>{xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} ''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work *<span style="color: gray;> {z} </span>sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in 'bglayer' above. * Currently {watermode}, {amplitude}, {wavelength} and {wavespeed} aren't working. Still, you need to fill them if you want to set {bgspeedratio}. '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. You'll probably want around 400 or -80 (But not more than -200 or 520, or they'll die). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 70693c5e063dff6028bf3ae13bb98ae565107887 3247 3246 2023-12-07T14:28:08Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases '''Last update on 2020.12.16 - by O Ilusionista''' * Native Functions: added @cmd projectile usage example =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it's 200 and for bikers it's 300. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For 'subtype biker' enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to "K'" (Yes, with an apostrophe ') * If the rider is only loaded with 'know' in models.txt, you should add 'load {name}' in this biker text to ensure that the 'rider' will fall off. ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However 'background' sets the bottommost layer while 'bglayer' sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don't use it on images that won't benefit from it. And don't use it for 'background' too since it's the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don't use it for background too. * {watermode} determines water effect. Currently there are 3 modes. **0 = No water effect for this bglayer **1 = Water effect for this bglayer is on **3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have **0 = No effect (default) **1 = Perspective & tile **2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {path}''' * {path} points to a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, 'palette' command (see below) won't work * frontpanels display in the order they are declared and repeat when they run out. You don't need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio which can't be changed. If you don't like it, use 'fglayer' below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path}<span style="color: gray;> {z} </span>{xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} ''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work *<span style="color: gray;> {z} </span>sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in 'bglayer' above. * Currently {watermode}, {amplitude}, {wavelength} and {wavespeed} aren't working. Still, you need to fill them if you want to set {bgspeedratio}. '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. You'll probably want around 400 or -80 (But not more than -200 or 520, or they'll die). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 02e665809a85ec33a8d05059feb20f73736f08b2 3248 3247 2023-12-07T14:54:07Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases '''Last update on 2023/12/04 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon} background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon} is a path which point to the image to be used as a neon (uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second.) '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path}<span style="color: gray;> {z} </span>{xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} ''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, 'palette' command (see below) won't work *<span style="color: gray;> {z} </span>sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in 'bglayer' above. * Currently {watermode}, {amplitude}, {wavelength} and {wavespeed} aren't working. Still, you need to fill them if you want to set {bgspeedratio}. '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 3451d29315da3bd901c1056295c477ac21904f6d 3249 3248 2023-12-07T15:03:31Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 93c31e481180821931533987bd32062c0c8dfa2e OpenBORManual 0 1314 3250 3249 2023-12-09T14:15:24Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! ac6c5a1191a05bbf0277b27ffb344658b133bf70 3251 3250 2024-01-01T14:48:06Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' </span> All information contained here was written for version 3 of OpenBOR (up to build 6391). Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 4ce05ae1b9f2501c383d27e50ce0f29bd3ba09d6 3252 3251 2024-01-01T14:57:08Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01_-_Font_size_144x144_for_letters_with_9x9_pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! b7e3dd7b3d224de6ea2984e8f5e869a268c9dbc0 3254 3252 2024-01-04T21:16:26Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[Image:Wall_tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 38d025cb7d607bf7cf382c39bd86c5d44f33c3dc 3263 3254 2024-01-04T23:02:12Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 65027419d26d8a94da80adb789c16c7ff18b1e30 3264 3263 2024-01-04T23:04:03Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! c4daa866d341ec92530cf5c10810648ec6ced2bb 3265 3264 2024-01-04T23:04:38Z O Ilusionista 167 /* Non-Graphics */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! a78202a43ff6efdc9b2136a586ec76065e62cff4 3266 3265 2024-01-04T23:05:51Z O Ilusionista 167 /* Non-Graphics */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional [[File:Wall tutorial2.png]] If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! b3705583c6dd589a28ed4fab61bf83b15b8206da 3267 3266 2024-01-04T23:06:59Z O Ilusionista 167 /* Non-Graphics */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available mod or pak instead of creating the ingredients one by one. Another way is by DL-ing BoREdit pack from http://www.senileteam.com/and expand it. The pack contains enough basic ingredients to start a mod. ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from http://www.lavalit.com/. You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 692c745d2d7fc174632e3926e65b0afbe1468768 3268 3267 2024-01-04T23:11:45Z O Ilusionista 167 /* Getting Started */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from https://www.chronocrash.com/forum/threads/paxplode-pack.3301/#post-93601 . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 60e2589633dde506a05be237c473151491e46ab9 3269 3268 2024-01-04T23:12:39Z O Ilusionista 167 /* Extracting an existing PAK File: */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from ChronoCrash: https://www.chronocrash.com/forum/threads/paxplode-pack.3301/ . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP is full. * This only works for players. Other entities doesn't have MP. '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is half. * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low. * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! d71ed16d35eecb87e8dd4f218a5e8580d1055624 3270 3269 2024-01-04T23:20:12Z O Ilusionista 167 /* Icon & Lifebar */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2023/12/07 - by O Ilusionista''' * Added findtitem and pickup functions * Fixed information about Bikers offscreenkill * Added more information about rider position and defautl palette * Added Steamer offscreenkill default value * Added missing parameters on frontpanel * Added many missing parameters on Background (xratio, zratio, etc) * Added missing parameters on Fglayer * Fixed information on Fglayer watermode =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from ChronoCrash: https://www.chronocrash.com/forum/threads/paxplode-pack.3301/ . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP any value higher than 2/3 of the max value * This only works for players. Other entities doesn't have MP. Getting 100 mp as an example, it will be same as * - iconmplow: lower than 33 * - iconmphalf: between 33 and 66 * - iconmphigh: higher than 66 (not when full, this is why it appears even if mp is not full) '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is between 1/3 and 2/3 of the max value * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low (1/3 of the max value) * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 4179a3fcf262b3567c390b21596bf75f0a8bec3f 3271 3270 2024-01-04T23:22:02Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2027/01/04 - by O Ilusionista''' * Fixed information about iconmphigh, iconmphalf and iconmplow. =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from ChronoCrash: https://www.chronocrash.com/forum/threads/paxplode-pack.3301/ . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP any value higher than 2/3 of the max value * This only works for players. Other entities doesn't have MP. Getting 100 mp as an example, it will be same as * - iconmplow: lower than 33 * - iconmphalf: between 33 and 66 * - iconmphigh: higher than 66 (not when full, this is why it appears even if mp is not full) '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is between 1/3 and 2/3 of the max value * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low (1/3 of the max value) * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 6f733302d4c39624c51ba438c8efa1209230e095 3272 3271 2024-01-04T23:24:20Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2027/01/04 - by O Ilusionista''' * Fixed the broken images links * Changed links to Paxplode and Basic Template to Chronocrash. * Fixed information about iconmphigh, iconmphalf and iconmplow =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from ChronoCrash: https://www.chronocrash.com/forum/threads/paxplode-pack.3301/ . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP any value higher than 2/3 of the max value * This only works for players. Other entities doesn't have MP. Getting 100 mp as an example, it will be same as * - iconmplow: lower than 33 * - iconmphalf: between 33 and 66 * - iconmphigh: higher than 66 (not when full, this is why it appears even if mp is not full) '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is between 1/3 and 2/3 of the max value * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low (1/3 of the max value) * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 8f38c74df9d86060c66f2c9b42dd95f5943b9262 File:01 - Font size 144x144 for letters with 9x9 pix.gif 6 1412 3253 2024-01-04T21:15:22Z O Ilusionista 167 wikitext text/x-wiki Font 9px 3f67922c806aa35d538918a729aa18ae81ce5ec9 File:02 - Font size 160x160 for letters with 10x10 pi.gif 6 1413 3255 2024-01-04T21:17:20Z O Ilusionista 167 wikitext text/x-wiki Font 10px 8752adad9eab27119d407067792c499f65e1a7f4 File:03 - Font size 192x192 for letters with 12x12 pi.gif 6 1414 3256 2024-01-04T21:18:02Z O Ilusionista 167 wikitext text/x-wiki Font 3 268f2a43d9fa90c706a7ab637e7c82305b83b896 File:04 - Font size 208x272 for letters with 13x17 pi.gif 6 1415 3257 2024-01-04T21:18:41Z O Ilusionista 167 wikitext text/x-wiki Font 13 1e567b76c65fa799ac79fcfc8ca7c3bbfb2f4ce6 File:05 - Font size 256x256 for letters with 16x16 pi.gif 6 1416 3258 2024-01-04T21:19:05Z O Ilusionista 167 wikitext text/x-wiki Font 15 87924e2a2b4d52c97af91faa1b9870884e215e85 File:06 - Font size 272x272 for letters with 17x17 pi.gif 6 1417 3259 2024-01-04T21:19:28Z O Ilusionista 167 wikitext text/x-wiki Font 17 cbd915b0edca90ba15f5dd4c30347c8326718b2e File:Openbor clip.png 6 1418 3260 2024-01-04T21:19:54Z O Ilusionista 167 wikitext text/x-wiki Drawmethod Clip 06510e39a800d55f109337746ebf3ec91daedcb6 File:Basemap.jpg 6 1419 3261 2024-01-04T22:58:06Z O Ilusionista 167 wikitext text/x-wiki Basemap draw 09520c943a666d541ba80b26c2c8afe4b2f15ae0 File:Wall tutorial2.png 6 1420 3262 2024-01-04T23:01:17Z O Ilusionista 167 wikitext text/x-wiki Wall explanation b23ab833dd4218ce0f43d163d50e77d52cd378fe Getting Started with Dreamcast development 0 694 3273 3235 2024-01-11T02:29:45Z Darc 1 /* Fedora-based Linux */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> ===This article is actively being worked on=== ''Work in progress - items to be added and/or edited'': Setting up debug link, building and burning a CD-R, setting up a first project, setting up an IDE, etc. =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 625d33567978c9ae1b4e0a56ea85a5e7459567e0 File:DreamParaPara Controller.jpg 6 1421 3274 2024-01-15T17:43:39Z GyroVorbis 13 wikitext text/x-wiki Sensor controller for DreamParaPara 1f2fd4c258108df6374661e34961830e0c4c3015 3275 3274 2024-01-15T17:45:57Z GyroVorbis 13 GyroVorbis uploaded a new version of [[File:DreamParaPara Controller.jpg]] wikitext text/x-wiki Sensor controller for DreamParaPara 1f2fd4c258108df6374661e34961830e0c4c3015 DreamParaPara Sensors 0 1422 3276 2024-01-15T17:46:14Z GyroVorbis 13 Created page with "[[File:DreamParaPara Controller.jpg|thumb|Sensor controller for DreamParaPara]]" wikitext text/x-wiki [[File:DreamParaPara Controller.jpg|thumb|Sensor controller for DreamParaPara]] f6f788d1b49a83b8e2757cfa92091c6bf6362100 DCWiki:Hardware 4 82 3277 2574 2024-01-15T17:47:37Z GyroVorbis 13 /* Hardware */ wikitext text/x-wiki == Hardware == {| style="width:100%" ! style="width: 50%"|Console and Peripherals ! style="width: 50%"|Modifications and Repair |- | style="padding: 5px;vertical-align:top"| * [[Hardware overview]], [[VMU hardware overview]] * [[Hardware variations]] * [[A/V connectivity]] * [[G2 bus]] ** [[Modem]], [[Broadband adapter]], [[LAN adapter]], [[Karaoke]], [[Zip drive]], [[G2 Terminator|Terminator]] * [[Maple bus]] ** [[Controller]], [[Keyboard]], [[Mouse]], [[Arcade stick]], [[Twin stick]], [[Race wheel]], [[Light gun]], [[Fishing rod]], [[Maracas]], [[DreamEye webcam]] ** [[Mission Stick]], [[Panther DC]], [[Densha de Go! controller]], [[Dance mat]], [[Pop'n controller]], [[DreamParaPara Sensors]], [[VCD remote]] ** [[VMU]], [[Memory card]], [[Jump pack]], [[Microphone]] ** [[Aftermarket adapters]] * [[Serial interface]] ** [[Neo Geo Pocket Color link cable]], [[VS cable]], [[MIDI adapter]], [[Coder's cable]], [[Serial SD card adapter]], [[Touchscreen]] | style="padding: 5px;vertical-align:top"| {| * [[Optical drive replacements]] * [[DCDigital]] HDMI, [[S/PDIF]], [[Internal VGA]], [[MIDI expansion|MIDI]] * [[BIOS modification]] * [[Region change]], [[NTSC/PAL mode enforcement]] * [[Power supply replacement]], [[Fan replacement]] * [[DreamPi]] * [[IDE hard drive modification]] * [[Overclocking]], [[32MB RAM expansion]] * [[VMU mods]] <br> * [[GD-ROM drive repair]] * [[PSU repair]] * Controller board: [[F1 fuse repair|Fuse repair]], [[battery replacement]] * [[Case whitening]] |} |} b80a7b04c3e4a7f7bb6774be1c1b0003564ed17f Maple bus 0 113 3278 2943 2024-01-21T03:11:04Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. Dreamcast initiates this sequence to a light gun once Dreamcast detects that the trigger has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB low within the SDCKB Occupancy once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held low until after Dreamcast brings SDCKA back high. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> ee3712a92f69bf4946aac420e76f1ec1a71e6bb0 3279 3278 2024-01-21T03:17:04Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === SDCKB Occupancy === The SDCKB occupancy start sequence looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. Dreamcast initiates this sequence to a light gun once Dreamcast detects that the trigger has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB low within the SDCKB Occupancy once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held low until after Dreamcast brings SDCKA back high. The SDCKB occupancy lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Maple Bus SDCKB Occupancy.png|Maple Bus SDCKB Occupancy]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 7af9020749506a7e8598d9598c9f2ad5473aa780 3281 3279 2024-01-21T18:24:31Z Tails86 160 Better describe light gun timing wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB low within the within the period of time marked blue in the below image once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held low by the light gun until after Dreamcast brings SDCKA back high. At that point, SDCKB must be brought back HIGH and the control of SDCKB must be let go by the light gun. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|thumb]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 2d23959b7864c35dd1f09d199131201bbf997ecf 3282 3281 2024-01-21T18:25:03Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for light gun triggering. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB low within the within the period of time marked blue in the below image once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held low by the light gun until after Dreamcast brings SDCKA back high. At that point, SDCKB must be brought back HIGH and the control of SDCKB must be let go by the light gun. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 25679edd45f37b4f546a533262998b80dcd423da 3283 3282 2024-01-21T18:28:04Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB low within the within the period of time marked blue in the below image once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held low by the light gun until after Dreamcast brings SDCKA back high. At that point, SDCKB must be brought back HIGH and the control of SDCKB must be let go by the light gun. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> d9635bc44074b87ba48f7a65a52d120e9859912a 3284 3283 2024-01-21T18:31:51Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB low within the within the period of time marked blue in the below image once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held low by the light gun until after Dreamcast brings SDCKA back high. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 0d8a8429797a621735d3c75564fc5f237a156b0e 3285 3284 2024-01-21T18:51:34Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the within the period of time marked blue in the below image once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> b39040fe7e1ad01cd933249f9eaec625a15bb603 3287 3285 2024-01-21T19:09:25Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the within the period of time marked blue in the below image once it detects that the electron beam of a CRT is in view of the lens of the light gun. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. A normal end sequence is then sent by the Dreamcast. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 6c8f0d8080883d7b04149bbbc3ad6fcbaf36e3b3 3288 3287 2024-01-21T19:11:02Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. A normal end sequence is then sent by the Dreamcast. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 8ce902f2862e4b16a08b2feaa3a1ecdb2cf3a0f1 3289 3288 2024-01-21T19:18:55Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. A normal end sequence is then sent by the Dreamcast. The duration of time given for beam detection lasts for a little longer than the time it takes to scan the entire screen. For a 60 Hz screen displaying 480i, this is a little longer than 33.3 milliseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 93d24a30c303942c3122a3be8d9864cf46772980 3290 3289 2024-01-21T21:16:46Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. A normal end sequence is then sent by the Dreamcast. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 30c79750ec80442b865262395d9e7f4152424699 3292 3290 2024-01-21T22:33:43Z Tails86 160 I was mistaken - no end sequence is sent on Light Gun CRT Beam Detection wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> ad5789857b43401bd7ed1e082ed211281cbea98c 3297 3292 2024-01-23T02:15:25Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. SDCKB is then held LOW by the light gun until after Dreamcast brings SDCKA back HIGH. At that point, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 7a74f3e2a5a503ab4fc5a6a8de271a1eee889988 3298 3297 2024-01-27T14:43:58Z Tails86 160 Light gun does not hold down SDCKB - it only stays low for the period that the beam is in view of the lens wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 20334b31540e09f9f14924b6d8964ff21c3080aa 3299 3298 2024-01-27T14:51:55Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the word format section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> 4ea9246390ff168e80d857e85849d3626d57e32c File:Light Gun CRT Beam Detect.png 6 1423 3280 2024-01-21T18:16:01Z Tails86 160 wikitext text/x-wiki Shows the bit sequence for light gun positioning on a CRT screen 287dbc96232490eb542db8b98c61d07d54cf323d 3286 3280 2024-01-21T19:08:19Z Tails86 160 Tails86 uploaded a new version of [[File:Light Gun CRT Beam Detect.png]] wikitext text/x-wiki Shows the bit sequence for light gun positioning on a CRT screen 287dbc96232490eb542db8b98c61d07d54cf323d 3291 3286 2024-01-21T22:32:23Z Tails86 160 Tails86 uploaded a new version of [[File:Light Gun CRT Beam Detect.png]] wikitext text/x-wiki Shows the bit sequence for light gun positioning on a CRT screen 287dbc96232490eb542db8b98c61d07d54cf323d User talk:Tails86 3 1424 3293 2024-01-21T22:35:52Z Tails86 160 Created page with "This image is incorrect - there should be no end sequence" wikitext text/x-wiki This image is incorrect - there should be no end sequence b4acc92030c581f5a0d5ab4d9dfffee0566afdda 3294 3293 2024-01-21T22:36:25Z Tails86 160 Blanked the page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Talk:VMU peripheral 1 1425 3295 2024-01-22T03:40:04Z Tails86 160 Created page with "I played around with the VMU buzzer control through the maple bus and came to the conclusion that it is probably referencing a clock frequency that is too high in this mode (seems like 2732 Hz). All I can play are high pitched tones. I also can't remember off the top of my head any games which used this feature." wikitext text/x-wiki I played around with the VMU buzzer control through the maple bus and came to the conclusion that it is probably referencing a clock frequency that is too high in this mode (seems like 2732 Hz). All I can play are high pitched tones. I also can't remember off the top of my head any games which used this feature. 514cf9eb52935714787c3d91b651471f3288f969 3296 3295 2024-01-23T02:04:32Z Tails86 160 I typed the wrong frequency wikitext text/x-wiki I played around with the VMU buzzer control through the maple bus and came to the conclusion that it is probably referencing a clock frequency that is too high in this mode (seems like 1 MHz). All I can play are high pitched tones. I also can't remember off the top of my head any games which used this feature. 2407b181f10750bda478fb00e027bad845c188fe Maple bus 0 113 3300 3299 2024-01-27T14:55:25Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == References == <references /> e9a5cca25fef6dc3f603632bb4c989ef4b52afac 3301 3300 2024-01-27T15:25:05Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. [[Controller peripheral]] [[VMU peripheral]] [[Jump pack peripheral]] == References == <references /> 86045952f79a2ee9cfb7747795c675db6a1ec529 3302 3301 2024-01-27T15:25:38Z Tails86 160 /* Peripheral Implementation */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> f8f2980472544e61c47a1748ec0a33ea048e2401 3303 3302 2024-01-27T22:05:53Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 97 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> 73c816f85e9020f41e7601f79f6674406de6f3d6 Rust on Dreamcast 0 1426 3304 2024-02-01T00:08:01Z Darc 1 Created page with "Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection toolchain. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (prefer..." wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection toolchain. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC ==rustc_codegen_gcc== ==gccrs== gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. 53f088eb26422c04d1d6c6b2b5adf065d6688713 3305 3304 2024-02-01T00:39:19Z Darc 1 wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC ==rustc_codegen_gcc== GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==gccrs== gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. e6378f1438f58d6e80c0b21bc4754b52383e4ac9 3306 3305 2024-02-01T00:42:08Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC ==rustc_codegen_gcc== GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ===Building a cross-compiling libgccjit.so for rustc_codegen_gcc=== ===Building rustc_codegen_gcc=== ===Creating a new project using Cargo=== ===Compiling individual modules into object files with rustc=== ==gccrs== gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. 3af24652c34964627501345d77ed7d35c7087ec6 3307 3306 2024-02-01T00:43:59Z Darc 1 wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== ==Building rustc_codegen_gcc== ==Creating a new project using Cargo== ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 5bf806440b7386a45efb1bebe366799dd83384a6 3308 3307 2024-02-01T01:35:11Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== - already have KOS toolchain and KOS set up - drop antoyo-gcc config and both patches into kos dc-chain dir - must have kos revision with enable-host-shared option (pending PR merge) - compile to /opt/toolchains/dc/rust, putting libgccjit.so at /opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so ==Building rustc_codegen_gcc== ==Creating a new project using Cargo== ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== ec66c95d886d32f5fadbcad1a6c3bfab4d2b2402 3309 3308 2024-02-01T01:45:57Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== * already have KOS toolchain and KOS set up * clone rust-for-dreamcast repo to /opt/toolchains/dc/rust * drop antoyo-gcc config and both patches into your kos dc-chain dir * must have kos revision with enable-host-shared option (pending PR merge) * compile toolchain to /opt/toolchains/dc/rust, putting libgccjit.so at /opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 44e6053fc70adc41687759d2cc01d848816b8611 3310 3309 2024-02-01T22:29:20Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== * already have KOS toolchain and KOS set up * clone rust-for-dreamcast repo to /opt/toolchains/dc/rust * drop antoyo-gcc config and both patches into your kos dc-chain dir * compile toolchain to /opt/toolchains/dc/rust, putting libgccjit.so at /opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 0b469b11ee6822c009b00a1cf8dbfadd542a5bc9 3321 3310 2024-02-03T03:52:59Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== * already have a KallistiOS setup (created a GCC SH4 cross-compiling toolchain and built KallistiOS with it, see [[Getting Started with Dreamcast development]] for more information) * already have a Rust installation, using your OS's package manager or [https://rustup.rs/ rustup] * clone rust-for-dreamcast repo to /opt/toolchains/dc/rust * drop antoyo-gcc config and both patches into your kos dc-chain dir * compile toolchain to /opt/toolchains/dc/rust, putting libgccjit.so at /opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== eb726b2a07b0c6e417829076a61468b38b8f64ac 3322 3321 2024-02-03T04:01:53Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. * clone rust-for-dreamcast repo to /opt/toolchains/dc/rust * drop antoyo-gcc config and both patches into your kos dc-chain dir * compile toolchain to /opt/toolchains/dc/rust, putting libgccjit.so at /opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 9308b293bb5272a97f632b47d4c7562213503b5a 3323 3322 2024-02-03T04:14:29Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile **libgccjit.so**, the cross-compiling shared library, for your system. This entails building another copy of GCC once more in its own directory under <code>/opt/toolchains/dc/rust</code>. Using <code>git</code>, clone the rust-for-dreamcast repository to /opt/toolchains/dc/rust: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a **libgccjit.so** will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 9790f5d0ed6bae953a84dcc5631532ac2564e257 3324 3323 2024-02-03T04:15:40Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of GCC once more in its own directory under <code>/opt/toolchains/dc/rust</code>. Using <code>git</code>, clone the rust-for-dreamcast repository to /opt/toolchains/dc/rust: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 6fa54f1a0f644a494494c15600aa1c682dbe42cb 3325 3324 2024-02-03T04:16:05Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of GCC once more in its own directory under <code>/opt/toolchains/dc/rust</code>. Using <code>git</code>, clone the rust-for-dreamcast repository to /opt/toolchains/dc/rust: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 3441d51f600b4c1bcc9fcc76ccb031de60f1f28c 3326 3325 2024-02-03T04:16:22Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of GCC once more in its own directory under <code>/opt/toolchains/dc/rust</code>. Using <code>git</code>, clone the rust-for-dreamcast repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 7bb004e81739b837a864f138e6689bcb39550143 3327 3326 2024-02-03T04:16:58Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of GCC once more in its own directory under <code>/opt/toolchains/dc/rust</code>. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 6d85b51cbd907feab96de683d8ee9f8310f69469 3328 3327 2024-02-03T04:27:56Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 323035b6c877d2f31248d310523347e457d3cee7 3329 3328 2024-02-03T04:28:21Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== * copy wrappers to /opt/toolchains/dc/bin (or add /opt/toolchains/dc/rust/wrappers to $PATH?) * clone rustc_codegen_gcc repo to /opt/toolchains/dc/rust/rustc_codegen_gcc * save /opt/toolchains/dc/rust/sh-elf/lib to gcc_path file * copy sh-elf.json to /opt/toolchains/dc/rust/rustc_codegen_gcc * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 6e71e8b34386fcf25019cfc714ba3a28a71b4478 3330 3329 2024-02-03T04:59:35Z Darc 1 wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration, and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== aa065534f8e3a9049a0d8b6460bd11f7c54d1851 3331 3330 2024-02-03T05:11:09Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 3784c11108fa740074a5d1fc6d1c86a8cdfadbdf 3332 3331 2024-02-03T06:07:00Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available, nor is borrow checking implemented. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== fee8064bdd7908a225066d56a38bfa6e069fd325 3336 3332 2024-02-03T20:41:08Z Darc 1 /* gccrs */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by compiling either GCC 14.0.1-dev or GCCRS git repo. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the GCCRS git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest GCCRS configuration is available within the [Rust for Dreamcast https://github.com/darcagn/rust-for-dreamcast] repository. Brief instructions follow for setting up the latest GCCRS toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== 21a8e5b0c9e8eb9026f03c64e2c1ad1b62990f3b 3337 3336 2024-02-03T20:42:58Z Darc 1 /* gccrs */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a Rust compiler frontend for GCC. This essentially means implementing a new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the GCCRS latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the GCCRS git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest GCCRS configuration is available within the [Rust for Dreamcast https://github.com/darcagn/rust-for-dreamcast] repository. Brief instructions follow for setting up the latest GCCRS toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a GCCRS-enabled toolchain== ==Setting up Makefiles to compile Rust modules== f06bd9af12b6e2a93c50abe44a5070ddef0c7d20 3338 3337 2024-02-03T21:00:44Z Darc 1 /* gccrs */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the GCCRS latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the GCCRS git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest GCCRS configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest GCCRS toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a GCCRS-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== 9020becbb2fb29a98c7663a059cdbf9ba14c843f 3339 3338 2024-02-03T21:13:26Z Darc 1 wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= gccrs implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the GCCRS latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the GCCRS git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest GCCRS configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest GCCRS toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a GCCRS-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with GCCRS, so in order to compile Rust code you will have to place your <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code>. If we assume the module file is named, <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so: #[no_mangle] pub extern fn main() -> i32 { [...] } Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your GCCRS compiler executable. 52bcc33624b24ff23ae361413d0a9108a9d222f7 3340 3339 2024-02-03T21:14:48Z Darc 1 /* gccrs */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so in order to compile Rust code you will have to place your <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code>. If we assume the module file is named, <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so: #[no_mangle] pub extern fn main() -> i32 { [...] } Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 666a507ff4c3a86d6d22ea6ce4478139280940e2 3341 3340 2024-02-03T22:04:04Z Darc 1 /* Setting up Makefiles to compile Rust modules */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so in order to compile Rust code you will have to place your <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code>. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so: #[no_mangle] pub extern fn main() -> i32 { [...] } Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 7693a2c4fd7ef4d8c79c51cd4bb85820de5c86b6 3342 3341 2024-02-03T22:08:18Z Darc 1 /* Setting up Makefiles to compile Rust modules */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so in order to compile Rust code we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code>. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so: #[no_mangle] pub extern fn main() -> i32 { [...] } Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. c8e55c74cb699fe273f2e813d04baa067bd896a0 3349 3342 2024-02-03T23:42:31Z Darc 1 /* Setting up Makefiles to compile Rust modules */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so in order to compile Rust code we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code>. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add that line to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. f1a61966aca9dafe89ae37d48744d386996f21be Development 0 2 3311 3186 2024-02-03T00:34:42Z Quzar 20 /* Engines */ - Adding link for Antiruins engine. wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === * [[Antiruins]] * [[Simulant]] ** [[Windows WSL2 Setup]] ** [[Generate profiling data]] === General === * [[Filesystem]] * [[Store Queues]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] c8ac226ad985b13ecc1cdd862b3ad9ebc0864d1a 3317 3311 2024-02-03T00:56:15Z Quzar 20 /* Engines */ wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === ''See'' [[Engine & Library]] === General === * [[Filesystem]] * [[Store Queues]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] 979539e02b46960ab3ca264c81c432f1ea31cfef Antiruins 0 1427 3312 2024-02-03T00:45:48Z Quzar 20 Initial create based on the github's README.md wikitext text/x-wiki '''[https://antiruins.com/engine Antiruins]''' is a minimal 2D engine for the SEGA Dreamcast that uses Lua as its only programming language. The engine backend is written in C and is precompiled, so you do not need the whole [[Getting_Started_with_Dreamcast_development#Setting_up_and_compiling_the_toolchain_with_the_dc-chain_script|Dreamcast toolchain]]. This greatly reduces compilation and debugging time and lets you focus on the game programming. === Features === The engine currently supports: * [x] Texture loading using .dtex and .png files. * [x] Music streaming using CDDA audio. * [x] .wav sound effect. * [x] Loading/saving LUA table to a memory card. * [x] Displaying images in the VMU. * [x] Playing DreamRoQ video. Currently supported but need better documentation/testing: * [ ] Sprite atlas and sprite animation. * [ ] Map loading. === Official Repository === https://gitlab.com/lerabot/antiruins {{DCWiki:Stub}} [[Category:Game Engines]] a7f766d52be45c614c16aa620e6a11891f5e52d3 Engine & Library 0 27 3313 1771 2024-02-03T00:47:32Z Quzar 20 /* Engine */ wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[[Simulant] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[[Antiruins]] - Minimal 2D game engine with Lua scripting by Lerabot. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] 30750ac56a17c856fbadabe2d60b533d2a10264d 3314 3313 2024-02-03T00:47:40Z Quzar 20 /* Engine */ wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[[Simulant]] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[[Antiruins]] - Minimal 2D game engine with Lua scripting by Lerabot. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] bab5fe7994565e410dbb83879375381a8c0c1712 3333 3314 2024-02-03T17:45:40Z Quzar 20 /* Audio */ wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[[Simulant]] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[[Antiruins]] - Minimal 2D game engine with Lua scripting by Lerabot. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade *[https://github.com/Aurelien34/DreamcastAicaSoundDriver] - A hardware accelerated S3M and sfx AICA driver. ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] a71333cdbb49a21fca49755d9f41a1541e997d63 3334 3333 2024-02-03T17:46:05Z Quzar 20 /* Graphics */ - Fix formatting wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[[Simulant]] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[[Antiruins]] - Minimal 2D game engine with Lua scripting by Lerabot. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *[https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade *[https://github.com/Aurelien34/DreamcastAicaSoundDriver] - A hardware accelerated S3M and sfx AICA driver. ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] 1dfd389a1f73bd816e6fe2e79663b9c1591109cc 3335 3334 2024-02-03T17:46:24Z Quzar 20 /* Audio */ wikitext text/x-wiki This list is an adaptation of the [https://github.com/dreamcastdevs/awesome-dreamcast awesome-dreamcast] repo on github. ==Tutorial== *[https://dreamcast.wiki Dreamcast.wiki] - A brand new wiki with up-to-date information about the Dreamcast. *[https://dcemulation.org/index.php?title=Development DCEmu Developement Wiki] - Great resource to start. Somewhat incomplete in certain aspect. *[https://github.com/dreamcastdevs/dreamcast_tutorial Dreamcast-tutorial Github] - A new-ish sets of tutorial with code example. Covers the basic (installing the toolchain, graphics, audio, controller) ==Framework== *[https://sourceforge.net/projects/cadcdev/ KOS] - The pseudo-OS that's been used in a lot of homebrew/indie. *[https://www.dreamsdk.org DreamSDK] - A multitool environment made for Windows. Maintained by [SiZiOUS](User:SiZiOUS) *[http://wiki.bennugd.org/index.php?title=Bennu_Wiki BennuGD] - A multi-platform engine *[https://github.com/FaucetDC/WincastCE WincastCE] - An experimental windows CE shell (?) *[https://github.com/DC-SWAT/DreamShell DreamShell] - The popular alternative operating system for loading games/app from SD Card and IDE Drive *[[libronin]] - an independent development library created by the DreamSNES team ==Engine== *[[Simulant]] - A general purpose 2D-3D engine in active developement. *[[nuQuake]] - Quake engine by MrNeo240 *[[RADquake]] - Quake engine by Ian Micheal *[https://github.com/ianmicheal/Dreambor6.0 DreamBOR - unofficial] - OpenBOR dreamcast port forked an improved by Ian Michael *[https://github.com/CaptainDreamcast/DolmexicaInfinite DolmexicaInfinite] - A Mugen-like engine for fighter games *[[Antiruins]] - Minimal 2D game engine with Lua scripting by Lerabot. ==Graphics== *[https://gitlab.com/simulant/ GLdcGLdc] - A OpenGL 1.2 implementation started by Kazade *[https://github.com/Kannagi/ LMP3DLMP3D] - A multi-platform 3D Lib. (*Looks abandoned but might be good for research*) *[https://github.com/multimediamike/dreamroq DreamROQ] - A ROQ video player. (*Stable, no sound*) ==Audio== *[https://gitlab.com/simulant/ALdc ALdc] - A OpenAL 1.2 implementation started by Kazade *https://github.com/Aurelien34/DreamcastAicaSoundDriver - A hardware accelerated S3M and sfx AICA driver. ==VMU== *[https://github.com/Protofall/Crayon-Utilities CrayonUtil] - Mostly tools for VMU icons, but also some texture converters. Made by [Protofall](https://github.com/Protofall) ==Utilities== *[https://github.com/CaptainDreamcast/prism Prism] - CaptainDreamcast's set of utilities for Physics, files loading, etc. (*untested*) ==Memory Management== ==Debugging== ==Random== *[https://github.com/Protofall/Homebrew-Tests Homebrew Tests (Protofall)] f8f0177f4ee768c1fe397624de104a9cc1efe561 Simulant 0 132 3315 399 2024-02-03T00:50:28Z Quzar 20 wikitext text/x-wiki '''[https://simulant-engine.appspot.com Simulant]''' is a cross-platform general-purpose game engine written in C++. It is designed with portability in mind, using minimal dependencies and targetting C++11 (rather than more modern versions of the language). The aim of Simulant is to create an easy-to-use game engine to allow building homebrew for older games consoles, as well as creating a great developer-experience on modern platforms. === Features === * Easy to use API, and getting simpler all the time! * Flexible rendering pipeline * Complex material scripting format * Loading of .obj models and the X-Wing vs Tie Fighter .opt format * Loading of MD2 animated models * Loading of Q2 BSP files (needs work) * Loading of heightmap terrains from image files * Advanced spatial hash partitioning and culling * Loading of JPG, PNG, TGA, WAL, PCX images and more! * Shortcut functions for loading 2D sprites, 2D backgrounds and 3D skyboxes * Simple scene graph functions * UI widgets (Button, Label, Progress Bar) * Basic rigid body physics using the Bounce library * Procedural functions for generating spheres, cubes, capsules, circles and rectangles * Functions for creating lights, multiple viewports and cameras === Tutorials === [[Generate_profiling_data]] === Official Repository === https://gitlab.com/simulant/simulant {{DCWiki:Stub}} [[Category:Game Engines]] 4f72bfccd01fd400cf1e1652bcdcf27966687530 3316 3315 2024-02-03T00:50:44Z Quzar 20 /* Tutorials */ wikitext text/x-wiki '''[https://simulant-engine.appspot.com Simulant]''' is a cross-platform general-purpose game engine written in C++. It is designed with portability in mind, using minimal dependencies and targetting C++11 (rather than more modern versions of the language). The aim of Simulant is to create an easy-to-use game engine to allow building homebrew for older games consoles, as well as creating a great developer-experience on modern platforms. === Features === * Easy to use API, and getting simpler all the time! * Flexible rendering pipeline * Complex material scripting format * Loading of .obj models and the X-Wing vs Tie Fighter .opt format * Loading of MD2 animated models * Loading of Q2 BSP files (needs work) * Loading of heightmap terrains from image files * Advanced spatial hash partitioning and culling * Loading of JPG, PNG, TGA, WAL, PCX images and more! * Shortcut functions for loading 2D sprites, 2D backgrounds and 3D skyboxes * Simple scene graph functions * UI widgets (Button, Label, Progress Bar) * Basic rigid body physics using the Bounce library * Procedural functions for generating spheres, cubes, capsules, circles and rectangles * Functions for creating lights, multiple viewports and cameras === Tutorials === [[Generate profiling data]] === Official Repository === https://gitlab.com/simulant/simulant {{DCWiki:Stub}} [[Category:Game Engines]] 127215223fe6d0ccc1e04c33cb33dbe84ee081fb Category:Game Engines 14 1428 3318 2024-02-03T00:57:12Z Quzar 20 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 NuQuake 0 110 3319 321 2024-02-03T00:57:42Z Quzar 20 wikitext text/x-wiki {{Release |Page name=nuQuake |titlescreen=nuquake-1.png |status=Released |releasedby=HaydenKow |name=nuQuake |genre=Action, FPS |release_date=December 2019 |unreleased=No }} {{Download |file= }} == Description == Homebrew Port of Quake using GLdc == Screenshots == <gallery mode=nolines heights=168 widths=240> nuquake-1.png|Title screen nuquake_ingame.png|First Scene Ingame </gallery> == Technical == * 640x480 3D Rendering via [[GLdc]] == Thanks == Thanks to [[Kazade]], Ian Michael, Bero, Rizzo. __NOTOC__ [[Category:Game Engines]] b4e97720f6d4c682cb953586b9e89a3135b02c49 RADquake 0 279 3320 988 2024-02-03T00:57:58Z Quzar 20 wikitext text/x-wiki ==Description== A port of Quake made by IMRTechnologies/Ian Micheal. *'''Type''': First-person shooter *'''Source code''': https://github.com/ianmicheal/Radquakemax [[Category:Game Engines]] 9f1b05e3d01be003120423161381389f10867467 Programming language support 0 1429 3343 2024-02-03T23:25:11Z Darc 1 Created page with "The following languages can be used in Sega Dreamcast programming: =Assembly languages= * '''SH4 assembly''', as the native machine code for the Dreamcast's SuperH processor * '''ARM assembly''', as the native machine code for the Dreamcast's AICA ARM7DI sound processor =Compiled languages= * '''C''', the predominant language for Sega Dreamcast development, via the GCC C compiler. * '''C++''', commonly used and very well-supported, via the GCC C++ compiler. * '''Object..." wikitext text/x-wiki The following languages can be used in Sega Dreamcast programming: =Assembly languages= * '''SH4 assembly''', as the native machine code for the Dreamcast's SuperH processor * '''ARM assembly''', as the native machine code for the Dreamcast's AICA ARM7DI sound processor =Compiled languages= * '''C''', the predominant language for Sega Dreamcast development, via the GCC C compiler. * '''C++''', commonly used and very well-supported, via the GCC C++ compiler. * '''Objective-C''', via the GCC Objective-C compiler. Preliminary support for Foundation framework via [https://gnustep.github.io/ GNUstep] is being developed. See [https://twitter.com/dinobj_c/status/1732399498977276154 Andrew Apperley's X account]. ** The GNU '''Objective-C++''' extension is available as well. * '''D''', via the GCC D compiler. Early support, see [https://twitter.com/lunafoxgirlvt/status/1736444629149487494 Luna's X account]. * '''Rust''', via rustc_codegen_gcc and libgccjit, or via gccrs. When using rustc_codegen_gcc, the core and alloc libraries are available, with bindings to KallistiOS being developed. See [[Rust on Dreamcast]] for more information. * '''Ada''', via GNAT. Initial work being done by [https://poulhies.fr/ Marc Poulhiès]. * '''Fortran''', via GFortran. Requires some work to create a cross-compiler, but does work. =Scripting/Interpreted languages= * Lua (available in [[kos-ports]]) * MicroPython (available in [[kos-ports]]) * Tcl (available in [[kos-ports]] * mRuby (available in [[kos-ports]] * AngelScript 07e87dac3c37a26102d415331249861e796bc7a3 3344 3343 2024-02-03T23:27:27Z Darc 1 /* Scripting/Interpreted languages */ wikitext text/x-wiki The following languages can be used in Sega Dreamcast programming: =Assembly languages= * '''SH4 assembly''', as the native machine code for the Dreamcast's SuperH processor * '''ARM assembly''', as the native machine code for the Dreamcast's AICA ARM7DI sound processor =Compiled languages= * '''C''', the predominant language for Sega Dreamcast development, via the GCC C compiler. * '''C++''', commonly used and very well-supported, via the GCC C++ compiler. * '''Objective-C''', via the GCC Objective-C compiler. Preliminary support for Foundation framework via [https://gnustep.github.io/ GNUstep] is being developed. See [https://twitter.com/dinobj_c/status/1732399498977276154 Andrew Apperley's X account]. ** The GNU '''Objective-C++''' extension is available as well. * '''D''', via the GCC D compiler. Early support, see [https://twitter.com/lunafoxgirlvt/status/1736444629149487494 Luna's X account]. * '''Rust''', via rustc_codegen_gcc and libgccjit, or via gccrs. When using rustc_codegen_gcc, the core and alloc libraries are available, with bindings to KallistiOS being developed. See [[Rust on Dreamcast]] for more information. * '''Ada''', via GNAT. Initial work being done by [https://poulhies.fr/ Marc Poulhiès]. * '''Fortran''', via GFortran. Requires some work to create a cross-compiler, but does work. =Scripting/Interpreted languages= * Lua (available in [[kos-ports]]) * MicroPython (available in [[kos-ports]]) * Tcl (available in [[kos-ports]] * mRuby (available in [[kos-ports]] * AngelScript * QuickJS bdb42e6321ddf54a04146fbb48fc58920032c7fc 3345 3344 2024-02-03T23:29:32Z Darc 1 /* Scripting/Interpreted languages */ wikitext text/x-wiki The following languages can be used in Sega Dreamcast programming: =Assembly languages= * '''SH4 assembly''', as the native machine code for the Dreamcast's SuperH processor * '''ARM assembly''', as the native machine code for the Dreamcast's AICA ARM7DI sound processor =Compiled languages= * '''C''', the predominant language for Sega Dreamcast development, via the GCC C compiler. * '''C++''', commonly used and very well-supported, via the GCC C++ compiler. * '''Objective-C''', via the GCC Objective-C compiler. Preliminary support for Foundation framework via [https://gnustep.github.io/ GNUstep] is being developed. See [https://twitter.com/dinobj_c/status/1732399498977276154 Andrew Apperley's X account]. ** The GNU '''Objective-C++''' extension is available as well. * '''D''', via the GCC D compiler. Early support, see [https://twitter.com/lunafoxgirlvt/status/1736444629149487494 Luna's X account]. * '''Rust''', via rustc_codegen_gcc and libgccjit, or via gccrs. When using rustc_codegen_gcc, the core and alloc libraries are available, with bindings to KallistiOS being developed. See [[Rust on Dreamcast]] for more information. * '''Ada''', via GNAT. Initial work being done by [https://poulhies.fr/ Marc Poulhiès]. * '''Fortran''', via GFortran. Requires some work to create a cross-compiler, but does work. =Scripting/Interpreted languages= * Lua (available in [[kos-ports]]) * MicroPython (available in [[kos-ports]]) * Tcl (available in [[kos-ports]]) * mRuby (available in [[kos-ports]]) * AngelScript * QuickJS 17f18a25f950bffdf440541bbc1bfdedda88c405 3348 3345 2024-02-03T23:37:05Z Darc 1 /* Compiled languages */ wikitext text/x-wiki The following languages can be used in Sega Dreamcast programming: =Assembly languages= * '''SH4 assembly''', as the native machine code for the Dreamcast's SuperH processor * '''ARM assembly''', as the native machine code for the Dreamcast's AICA ARM7DI sound processor =Compiled languages= * '''C''', the predominant language for Sega Dreamcast development, via the GCC C compiler. * '''C++''', commonly used and very well-supported, via the GCC C++ compiler. * '''Objective-C''', via the GCC Objective-C compiler. Preliminary support for Foundation framework via [https://gnustep.github.io/ GNUstep] is being developed. See [https://twitter.com/dinobj_c/status/1732399498977276154 Andrew Apperley's X account]. ** The GNU '''Objective-C++''' extension is available as well. * '''Rust''', via rustc_codegen_gcc and libgccjit, or via gccrs. When using rustc_codegen_gcc, the core and alloc libraries are available, with bindings to KallistiOS being developed. See [[Rust on Dreamcast]] for more information. * '''D''', via the GCC D compiler. Early support, see [https://twitter.com/lunafoxgirlvt/status/1736444629149487494 Luna's X account]. * '''Ada''', via GNAT. Initial work being done by [https://poulhies.fr/ Marc Poulhiès]. * '''Fortran''', via GFortran. Requires some work to create a cross-compiler, but does work. =Scripting/Interpreted languages= * Lua (available in [[kos-ports]]) * MicroPython (available in [[kos-ports]]) * Tcl (available in [[kos-ports]]) * mRuby (available in [[kos-ports]]) * AngelScript * QuickJS b4a6f7f2b6971bba1f0be72af1a4cd5c92279107 Kos-ports 0 1430 3346 2024-02-03T23:32:37Z Darc 1 Created page with "'''kos-ports''' is a package manager and repository containing development library add-ons for [[KallistiOS]]. * See [kos-ports https://github.com/KallistiOS/kos-ports]" wikitext text/x-wiki '''kos-ports''' is a package manager and repository containing development library add-ons for [[KallistiOS]]. * See [kos-ports https://github.com/KallistiOS/kos-ports] c428f241aa5fc22b99f2ae093cd7301bf0a8f8f4 3347 3346 2024-02-03T23:32:49Z Darc 1 wikitext text/x-wiki '''kos-ports''' is a package manager and repository containing development library add-ons for [[KallistiOS]]. * See [https://github.com/KallistiOS/kos-ports kos-ports] a9df5c8417745bc67150a10df77ddedfd8d6442c Rust on Dreamcast 0 1426 3350 3349 2024-02-03T23:45:13Z Darc 1 /* Setting up Makefiles to compile Rust modules */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like Vec, String, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add that line to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. b96ab31905be143e2a9031257657452857d897c2 3351 3350 2024-02-03T23:46:24Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add that line to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 112a6031a0abaaa6c35fb3f61e24e78b6b2aa9f8 3352 3351 2024-02-03T23:47:26Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add that line to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. f670a21e1885043342ad0064f7db8ac5a80eefde 3358 3352 2024-02-04T00:42:23Z Darc 1 /* Setting up Makefiles to compile Rust modules */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Copy the architecture configuration file, <code>sh-elf.json</code>, to its place: cp /opt/toolchains/dc/rust/misc/sh-elf.json /opt/toolchains/dc/rust/rustc_codegen_gcc/sh-elf.json * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * y.sh clean * y.sh prepare --cross * y.sh build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 71b1a8e314518c75db7d424f2eda691e0c0f8b83 3359 3358 2024-02-04T01:03:14Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. Let's add them to our environment's PATH now: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * <code>./y.sh clean all</code> * <code>./y.sh prepare --cross</code> * <code>./y.sh build --release --features master --target-triple sh-elf --target /opt/toolchains/dc/rust/misc/sh-elf.json</code> ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. e1e1c1143e456ec1813174e0d1ab0c6c555072a4 3360 3359 2024-02-04T01:11:26Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add them to our <code>PATH</code> environment variable, but '''rustc_codegen_gcc''' also needs the toolchain's binaries in the <code>PATH</code>. Let's add both: export PATH="/opt/toolchains/dc/rust/bin:/opt/toolchains/dc/rust/sh-elf/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path * patch out duplicate symbols in src/context.rs * add SH4 precision mode to src/base.rs * patch build_system/src/config.rs to alter default linker call * patch build_sysroot/Cargo.toml to remove std and test from being pulled in * <code>./y.sh clean all</code> * <code>./y.sh prepare --cross</code> * <code>./y.sh build --release --features master --target-triple sh-elf --target /opt/toolchains/dc/rust/misc/sh-elf.json</code> ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. b91319ea504b04405c68e2b70524e9141c74ac6e 3361 3360 2024-02-04T01:14:47Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add them to our <code>PATH</code> environment variable, but '''rustc_codegen_gcc''' also needs the toolchain's binaries in the <code>PATH</code>. Let's add both: export PATH="/opt/toolchains/dc/rust/bin:/opt/toolchains/dc/rust/sh-elf/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to run it every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: patch -p1 < ../patches/*.diff Now let's build '''rustc_codegen_gcc'''! ./y.sh clean all ./y.sh prepare --cross ./y.sh build --release --features master --target-triple sh-elf --target /opt/toolchains/dc/rust/misc/sh-elf.json ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. e19cbe641d89fb5b3341967316598778e23ecfe9 3362 3361 2024-02-04T01:27:31Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add both the path to those scripts and the path to our newly built toolchain our <code>PATH</code> environment variable. Additionally, we need to set an environment variable for the installation path of '''rustc_codegen_gcc'''. Let's add both: export PATH="/opt/toolchains/dc/rust/bin:/opt/toolchains/dc/rust/sh-elf/bin:$PATH" export CG_GCCJIT_DIR="/opt/toolchains/dc/rust/rustc_codegen_gcc" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''russftc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: patch -p1 < ../patches/*.diff Now let's build '''rustc_codegen_gcc'''! ./y.sh clean all ./y.sh prepare --cross ./y.sh build --release --features master --target-triple sh-elf --target /opt/toolchains/dc/rust/misc/sh-elf.json ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 5a5e6c7349101fb8016177f614e862ae380ded17 3363 3362 2024-02-04T01:27:50Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add both the path to those scripts and the path to our newly built toolchain our <code>PATH</code> environment variable. Additionally, we need to set an environment variable for the installation path of '''rustc_codegen_gcc'''. Let's add both: export PATH="/opt/toolchains/dc/rust/bin:/opt/toolchains/dc/rust/sh-elf/bin:$PATH" export CG_GCCJIT_DIR="/opt/toolchains/dc/rust/rustc_codegen_gcc" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: patch -p1 < ../patches/*.diff Now let's build '''rustc_codegen_gcc'''! ./y.sh clean all ./y.sh prepare --cross ./y.sh build --release --features master --target-triple sh-elf --target /opt/toolchains/dc/rust/misc/sh-elf.json ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 84312835aead9dd06e4969d7b1199644053d1335 3364 3363 2024-02-04T01:44:01Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add both the path to those scripts and the path to our newly built toolchain our <code>PATH</code> environment variable. Additionally, we need to set an environment variable for the installation path of '''rustc_codegen_gcc'''. Let's add both: export PATH="/opt/toolchains/dc/rust/bin:/opt/toolchains/dc/rust/sh-elf/bin:$PATH" export CG_GCCJIT_DIR="/opt/toolchains/dc/rust/rustc_codegen_gcc" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: patch -p1 < ../patches/*.diff Now let's build '''rustc_codegen_gcc'''! rust-dc clean rust-dc prepare rust-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 537aa6acf3f009181952c93677f4cd1aabdbb428 3369 3364 2024-02-04T02:50:57Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: patch -p1 < ../patches/*.diff Now let's build '''rustc_codegen_gcc'''! rust-dc clean rust-dc prepare rust-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 7b7045bffd78f4a8b2935935cd92abf202f811e2 3370 3369 2024-02-04T03:15:04Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rust-dc patch Now let's build '''rustc_codegen_gcc'''! rust-dc prepare rust-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. cdfab4973c8140511e7c465bb885143798177340 3371 3370 2024-02-04T03:33:38Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rust-dc patch Now let's build '''rustc_codegen_gcc'''! rust-dc prepare rust-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== '''TODO''' =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. ab9ec67160b41c27794a3e025925bb0627649f33 3372 3371 2024-02-04T04:37:27Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rust-dc patch Now let's build '''rustc_codegen_gcc'''! rust-dc prepare rust-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 1e5efeddb8fce7c0e8ac3503abca1de789da316a 3373 3372 2024-02-04T04:39:54Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rust-dc patch Now let's build '''rustc_codegen_gcc'''! rust-dc prepare rust-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> An example "Hello, world!"-style program built in this style which demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 43c2ad7a17a037e0d51c56ef40b953c70226bca2 3374 3373 2024-02-04T04:45:37Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> An example "Hello, world!"-style program built in this style which demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 297e6808346bf0350343e116f7d6fa4803e35fe8 3375 3374 2024-02-04T04:49:07Z Darc 1 wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an API for an embeddable just-in-time code generator using GCC, useful for creating programs like interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler with the libgccjit API to generate machine code from Rust using the GCC backend. With this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but it may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== First, we must compile <code>libgccjit.so</code>, the cross-compiling shared library, for your system. This entails building another copy of the SH4 toolchain once more in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the rustc_codegen_gcc to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> An example "Hello, world!"-style program built in this style which demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 9b424753e114eb2300e1a29d9bb16abde2e3348b 3376 3375 2024-02-04T04:55:44Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> An example "Hello, world!"-style program built in this style which demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 2b2fb884d750d3856001dff5b732beddf8b41828 3377 3376 2024-02-04T04:56:04Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!"-style program built in this style which demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 8c877ae954f1bfc822bfd49d2c5b3886a3e602f5 3378 3377 2024-02-04T04:56:37Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 45eb25e3b3c8b92af450c79557cb540495441a65 3379 3378 2024-02-04T04:58:19Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast's CPU SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 3942eb919440c4513746187226685642acace66c 3380 3379 2024-02-04T05:00:27Z Darc 1 wikitext text/x-wiki Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. b244e12019ace838fda710cc36509c7f2da34e09 3381 3380 2024-02-04T05:00:58Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== * create an empty staticlib crate with target in .cargo/config * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. e3140bbd3110612add4d8b57ec38b2d2385e08d1 3382 3381 2024-02-04T05:28:13Z Darc 1 /* Creating a new project using Cargo */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example Change the crate type in <code>Cargo.toml</code> by adding the following: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. cae3bf1292f0a9400e3e7c4f48f3d9ec837d60e6 3383 3382 2024-02-04T05:44:54Z Darc 1 /* Creating a new project using Cargo */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 0b5e7267b8222e112586518cf8759706bdeb2b1d 3384 3383 2024-02-04T05:46:48Z Darc 1 /* Creating a new project using Cargo */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> Preliminary support exists for developing for the Dreamcast using the Rust programming language. This is a bit of a challenge, however, as the official Rust compiler is based on the LLVM toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with GCC, the GNU Compiler Collection. There exists two solutions to this problem: * rustc_codegen_gcc: A libgccjit codegen backend for rustc (preferred method) * gccrs: a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> This function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 13c43c58e072e964d0f0b24da234684e9243b4f6 3385 3384 2024-02-04T06:08:28Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> There is currently preliminary support for developing Dreamcast applications using the [https://www.rust-lang.org/ Rust] programming language. This presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> This function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. f76d89ce8f13fda27f042fab63956be30789eb30 3386 3385 2024-02-04T06:12:17Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> There is currently preliminary support for developing Dreamcast applications using the [https://www.rust-lang.org/ Rust] programming language. This presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> This function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 75cd09296dd1564a7f22bee4ee55a28aac4b5096 3387 3386 2024-02-04T06:31:56Z Darc 1 /* Creating a new project using Cargo */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> There is currently preliminary support for developing Dreamcast applications using the [https://www.rust-lang.org/ Rust] programming language. This presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> The <code>rust_start()</code> function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. b425573cb798e4b2b0aa58bfbd3f9dd22c0a5847 3398 3387 2024-02-07T01:00:56Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> Support for Rust on Dreamcast is early, but currently possible if one is willing to endure the experimental nature of setting it up and lack of stability in implementations. Doing so presents a bit of a challenge as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> The <code>rust_start()</code> function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 4e5b9d4aa12d2d9875d81299ef09ebe352878297 3399 3398 2024-02-07T01:14:18Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> Support for Rust on Dreamcast is early, but currently possible if one is willing to endure the experimental nature of setting it up and lack of stability in implementations. Doing so presents a bit of a challenge as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust kos-rust crate], we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support. '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. GCC includes a component called '''libgccjit''' which provides an interface for an embeddable just-in-time code generator, useful for creating interpreters. However, this component can also be used to generate code ahead of time as well. '''rustc_codegen_gcc''' is a project which interfaces the official Rust compiler frontend with the '''libgccjit''' API to generate machine code from Rust using the GCC backend. Using this, we can compile Rust programs for Dreamcast using familiar compiler tools such as <code>rustc</code> and <code>cargo</code>! The familiar borrow checker still works, and one can write <code>#![no_std]</code> crates with full <code>libcore</code> support. An experimental crate binding with [[KallistiOS]] provides <code>liballoc</code> functionality such as a heap and familiar collections like <code>Vec</code>, <code>String</code>, etc. as well. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> The <code>rust_start()</code> function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. d038dc519351549efe4758666b0a5a61811f831c Getting Started with Dreamcast development 0 694 3353 3273 2024-02-04T00:03:32Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 3ed341a9c2f729f5cc8048ae992fa30858d69fc3 3354 3353 2024-02-04T00:07:50Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Dependencies required: Homebrew meson libisofs Debian/Ubuntu libisofs-dev meson ninja-build Fedora meson ninja-build Arch meson Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' =Further reading= '''TODO''': Links to articles for using gdb, integrating the dev setup with an IDE, etc. e.g. * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] 48e0b0198ea7852fafe4cc1496318813e22a3e68 3355 3354 2024-02-04T00:13:25Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Further= At this point, you will have a cross-compiler built so that you can generate programs for your Dreamcast from code. KallistiOS, the Dreamcast development library and operating system, is built, as is its associated packages within kos-ports, and all of its example programs. At this point, you will likely want to view some of the following articles: * Setting up an IDE for Dreamcast development ** [[Qt Creator Dreamcast Development Environment]] ** [[CLion Debugging]] ** [[Visual Studio Code]] * [[Creating a first project with KallistiOS]] * [[Using a debug link]] * [[Burning an example to CD-R]] =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Dependencies required: Homebrew meson libisofs Debian/Ubuntu libisofs-dev meson ninja-build Fedora meson ninja-build Arch meson Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) =Creating your first project= '''TODO''': ''Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it'' cc3f03f90ef4ad692d4df6aaec880bcfeb42327d 3356 3355 2024-02-04T00:14:14Z Darc 1 /* Creating your first project */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Further= At this point, you will have a cross-compiler built so that you can generate programs for your Dreamcast from code. KallistiOS, the Dreamcast development library and operating system, is built, as is its associated packages within kos-ports, and all of its example programs. At this point, you will likely want to view some of the following articles: * Setting up an IDE for Dreamcast development ** [[Qt Creator Dreamcast Development Environment]] ** [[CLion Debugging]] ** [[Visual Studio Code]] * [[Creating a first project with KallistiOS]] * [[Using a debug link]] * [[Burning an example to CD-R]] =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Dependencies required: Homebrew meson libisofs Debian/Ubuntu libisofs-dev meson ninja-build Fedora meson ninja-build Arch meson Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) f9b2e19fbe338b286b5523e1316cffe82d60edad 3357 3356 2024-02-04T00:14:32Z Darc 1 /* Further */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Further= At this point, you will have a cross-compiler built so that you can generate programs for your Dreamcast from code. KallistiOS, the Dreamcast development library and operating system, is built, as is its associated packages within kos-ports, and all of its example programs. At this point, you will likely want to view some of the following articles: * Setting up an IDE for Dreamcast development ** [[Qt Creator Dreamcast Development Environment]] ** [[CLion Debugging]] ** [[Visual Studio Code]] * [[Creating a first project with KallistiOS]] ('''TODO''': Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it) * [[Using a debug link]] * [[Burning an example to CD-R]] =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Dependencies required: Homebrew meson libisofs Debian/Ubuntu libisofs-dev meson ninja-build Fedora meson ninja-build Arch meson Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) e4edd8e76c754b8cfaa64c59728beff93c5d2c69 Maple bus 0 113 3365 3303 2024-02-04T02:33:30Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 99 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> 59b04e90b3dc549e8af05f8698d9d1e6e3ff1202 3366 3365 2024-02-04T02:34:38Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements both Controller and either Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 99 nanoseconds. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> 22b4e3029a54083c692b183dafcca0a79f6ba82e 3367 3366 2024-02-04T02:38:52Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements both Controller and either Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 99 nanoseconds. A beam detection must occur within the first 16.68 milliseconds or the shot won't count, and the Dreamcast may also flag the light gun as faulty. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> b7e2ef3bdeaa9b71bc1db2c39d597482561baaed 3368 3367 2024-02-04T02:42:32Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements both Controller and either Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines, the time window for each pixel on a 60 Hz screen is about 99 nanoseconds. If beam detection only occurs in the last 16.68 milliseconds, the shot won't count, and the Dreamcast may also flag the light gun as faulty. If no beam is detected, meaning SDCKB remains HIGH throughout the entire period, then the game normally treats this as a gun reload event. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> a7849b7155689e2d7ea4a3579c7dcb3b0cc06318 Development 0 2 3388 3317 2024-02-04T15:13:42Z Tchan 166 /* Other */ add link to new page: compiling for naomi wikitext text/x-wiki === Getting started === * [[Getting Started with Dreamcast development]] -- start here! ====Ready-to-use environments==== * [[Docker images]] * [[DreamSDK]] (Windows only) ====[[KallistiOS]]==== * Building on Linux, macOS, Windows Subsystem for Linux ** see [[Getting Started with Dreamcast development|''Getting Started with Dreamcast development'']] * [[Building KOS on Cygwin]] * [[Building KOS on MinGW/MSYS]] * [[Building KOS on MinGW-w64/MSYS2]] * [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation] ====Other==== * [[Using Ruby for Sega Dreamcast development]] (experimental) * [[Compiling for Naomi]] === Build & test === * [[Building your project]] * [[Emulators]] * [[Broadband adapter]] / [[LAN adapter]] ** [[Using dcload-ip with Linux]] ** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux) * [[Coder's cable]] === Environments and IDEs === * [[Qt Creator Dreamcast Development Environment]] * [[CLion Debugging]] * [[Visual Studio Code]] === Tools & utilities === * [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]] * [[Using dcprof]] === Releasing your project === * Plain files * Disc image * Selfboot Inducer package === Engines === ''See'' [[Engine & Library]] === General === * [[Filesystem]] * [[Store Queues]] * [[Romdisk Swapping]] * [https://mc.pp.se/dc/hw.html Marcus Comstedt's Dreamcast Hardware Reference] === Graphics === * [[Texture Formats]] * [[Graphics APIs]] * [[Paletted Textures]] * [[2D Rendering Without PVR]] * [[Twiddling]] * PVR ** [[PowerVR Introduction]] ** [[PVR Spritesheets]] * [[GLdc]] ** [[Drawing 2D sprites using GLdc]] ** [[Drawing 3D shapes using GLdc]] ** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer] * Others ** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture] ** [[Notes on fillrate and drawing large textures]] ** [[KMG Textures]] ** [[Loading PNG images as OpenGL textures]] === Audio === * [[Playing SFX]] * [[Streaming audio]] === Maple === * Controller input === VMU === * [[File Types]] * [[Save/Load file]] * [[Show icon]] * [[Play tone]] * [[VMU_development|Game Development]] === Optimization === * [[GCC-SH4 tips]] * [[SH4 in Compiler Explorer]] * [[Fast SH4 Vertex Processing]] * [[Useful programming tips]] * [[Efficient usage of the Dreamcast RAM]] * Registers * DMA * TA * PVR === Website Development === *[[Development Resources]] === Random Snippets === * [[Objdump]] 867553e9e8864b190c02ac6dc46ff7825dc0d557 Compiling for Naomi 0 1431 3389 2024-02-04T15:31:04Z Tchan 166 initial version wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLDC, you need recent GLdc code (you need commit bd17c995 of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb ) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit TODO of TODO feb) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf 5e8df98f7624fbab7339306edacdffe07ccd925a 3390 3389 2024-02-04T15:33:37Z Tchan 166 added commit wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLDC, you need recent GLdc code (you need commit bd17c995 of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb ) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit d059b92 of 04 feb) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf d3f1337d70db47061cdb1722b8a1482fcf68d829 3391 3390 2024-02-04T15:39:55Z Tchan 166 added info that kos/kos-ports need to be built for Naomi wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLDC, you need recent GLdc code (you need commit bd17c995 of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb ) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit d059b92 of 04 feb) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf 8ef1b25061463c8cb4eab78680a8ddeb9c308f12 3392 3391 2024-02-04T15:41:29Z Tchan 166 added 2024 to the commit infos wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLDC, you need recent GLdc code (you need commit bd17c995 of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb 2024) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit d059b92 of 04 feb 2024) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf 893856ee2f04ce33effa5dd13b5c4680b64750a6 3393 3392 2024-02-04T16:43:27Z Tchan 166 wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLdc, you need recent GLdc code (you need commit bd17c995 of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb 2024) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit d059b92 of 04 feb 2024) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf e8e7008669c658679235467e64b38cb87e7bfbb2 3394 3393 2024-02-04T17:09:41Z Tchan 166 /* Prerequisites */ added gitlab link to required commit wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLdc, you need recent GLdc code (you need at least commit [https://gitlab.com/simulant/GLdc/-/commit/b1223cfd1cc6a829c8acccc28220e15b5383522f b1223cfd] of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb 2024) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit d059b92 of 04 feb 2024) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf 19ce701b5a71294ee85dadac258e372c5d6b4302 3395 3394 2024-02-04T17:11:12Z Tchan 166 /* Send your file to a Naomi via a serial cable */ added commit link for kos wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLdc, you need recent GLdc code (you need at least commit [https://gitlab.com/simulant/GLdc/-/commit/b1223cfd1cc6a829c8acccc28220e15b5383522f b1223cfd] of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb 2024) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit [https://github.com/KallistiOS/KallistiOS/commit/d059b922625b6fd1f05dac4381b48d0ba571650b d059b92] of 04 feb 2024) * upload the .ELF via your regulat dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf 1843cd58f1dc35c6a0e7b53cb67774194f68b3f6 3396 3395 2024-02-04T17:13:16Z Tchan 166 /* Send your file to a Naomi via a serial cable */ wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLdc, you need recent GLdc code (you need at least commit [https://gitlab.com/simulant/GLdc/-/commit/b1223cfd1cc6a829c8acccc28220e15b5383522f b1223cfd] of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb 2024) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit [https://github.com/KallistiOS/KallistiOS/commit/d059b922625b6fd1f05dac4381b48d0ba571650b d059b92] of 04 feb 2024) * upload the .ELF via your usual dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf c16443c6193b2efc350b153d250e0a5987c2b686 3397 3396 2024-02-04T18:42:50Z Tchan 166 /* Send your file to a Naomi via a serial cable */ wikitext text/x-wiki KallistiOS is able to produce executables that can run on the Sega Naomi arcarde boards. == Prerequisites == * if you want to use GLdc, you need recent GLdc code (you need at least commit [https://gitlab.com/simulant/GLdc/-/commit/b1223cfd1cc6a829c8acccc28220e15b5383522f b1223cfd] of 03 feb 2024) * download (git clone) kos & kos-ports into separate folders, eg /kosnaomi & /kos-portsnaomi * adapt the following in /kosnaomi/environ.sh: KOS_SUBARCH="naomi" KOS_BASE <- point to your naomi kos folder KOS_PORTS <- point to your naomi kos-ports folder * Build these /kosnaomi & /kos-portsnaomi * if you want to use raylib, you need recent raylib4Dreamcast code (you need commit TODO of 04 feb 2024) == Compilation to a .ELF == Example compilation for a raylib example: * Go to the folder that contains your example, eg: cd /opt/toolchains/dc/kos-portsnaomi/raylib4Dreamcast/samples/shapes/basic_shapes * source the environ.sh of your naomi folder: source /opt/toolchains/dc/kosnaomi/environ.sh * build the .elf for Naomi: make == Converting an .ELF to a .DAT to send to a Naomi DIMM == * Convert your Naomi-built KOS .ELF to a .BIN file: /opt/toolchains/dc/sh-elf/sh-elf/bin/objcopy -R .stack -O binary raylib.elf raylib_nao.bin * convert your Naomi .BIN to a .DAT file: /opt/toolchains/dc/kosnaomi/utils/naomibintool/naomibintool build raylib_nao.dat -d DEVELOPERNAME -t GAMETITLE -b raylib_nao.bin == Send your .DAT file to a Naomi DIMM via ethernet == * Assuming the IP address of the Naomi is 192.168.1.202: /opt/toolchains/dc/kosnaomi/utils/naominetboot/naominetboot -t 192.168.1.202 -x raylib_nao.dat -a == Send your .ELF file to a Naomi via a serial cable == If you don't have a DIMM board, or just want to use dc-tool-serial to upload a Naomi .elf via a serial cable, you need: * a custom bios containing dc-load-ser * recent KallistiOS code (you need commit [https://github.com/KallistiOS/KallistiOS/commit/d059b922625b6fd1f05dac4381b48d0ba571650b d059b92] of 04 feb 2024) * upload the .ELF via your usual dc-tool-ser command, eg: dc-tool-ser -b 1562500 -t /dev/ttyUSB0 -x raylib.elf 7c0d9977c6b0afec14cc3fd9fb0f2902b7c4dfa8 Rust on Dreamcast 0 1426 3400 3399 2024-02-07T01:21:11Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> Support for Rust on Dreamcast is early, but currently possible if one is willing to endure the experimental nature of setting it up and lack of stability in implementations. Doing so presents a bit of a challenge as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']. '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Compiling individual modules into object files with rustc== A wrapper script named <code>rustc-dc</code> is included for generating <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at <code>examples/rustc-hello</code>. ==Creating a new project using Cargo== A wrapper script called <code>cargo-dc</code> is included to simplify invoking <code>cargo</code> using '''rustc_codegen_gcc'''. When using <code>cargo</code> in this setup, we will compile our program and all crate code into a static library <code>.a</code> file and link it with an empty KallistiOS <code>Makefile</code>-style project. Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> * add kos-rs crate from /opt/toolchains/dc/rust/kos-rs path Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_start(_argc: i32, _argv: *const u8) -> i32 { [...] return 1337; } </syntaxhighlight> The <code>rust_start()</code> function will serve as the entry point to your Rust code. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. e11eaacee22814f5b2c25cbf64aa50a55bfa401a 3401 3400 2024-02-07T02:19:20Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> Support for Rust on Dreamcast is early, but currently possible if one is willing to endure the experimental nature of setting it up and lack of stability in implementations. Doing so presents a bit of a challenge as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']. '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 6888623bd30a954f613a2fb349c35b2ca073a4e6 3402 3401 2024-02-07T02:44:08Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> Support for Rust on Dreamcast is early, but currently possible if one is willing to endure the experimental nature of setting it up and lack of stability in implementations. Doing so presents a bit of a challenge as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']. '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. b3f764a88a87164a37023a8b6180b86290f17e7b 3405 3402 2024-02-08T21:55:09Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its performance and ability to operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 5c066be4b7ed37fe02f5c0cb3d5f7951422c98b3 3406 3405 2024-02-08T21:55:58Z Darc 1 wikitext text/x-wiki <div style="float:right;">__TOC__</div> Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. e6d2140ad3d5a5857807f420571a05e32f90946c 3408 3406 2024-02-08T21:58:51Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 32234587817e99fc82fdcfdabe703ce0b8259a4f 3409 3408 2024-02-09T22:10:18Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for std library * Create bindings for KOS APIs =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. d2b46049e9b0a2856576389d7f5d43a782ebd0a9 3410 3409 2024-02-09T22:11:21Z Darc 1 /* Future goals */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for std library * Create bindings for KOS APIs * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 6030179084d07f2574cff82d7d08829384c86e0a 3412 3410 2024-02-10T13:42:00Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc_codegen_gcc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for std library * Create bindings for KOS APIs * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. f23b0fa2e6e23cdf96f72206070dc8777b00d5de 3413 3412 2024-02-10T13:59:25Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for std library * Create bindings for KOS APIs * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. daf7b209c03468ef185c5e8ec7fa36206165068d 3414 3413 2024-02-10T14:12:12Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for std library * Create bindings for KOS APIs * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. c6ac2923b5e65527c3da2e48742b086e2892a9aa 3415 3414 2024-02-10T14:15:08Z Darc 1 /* Future goals */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. This setting is available in the <code>environ.sh</code>, but changing the setting may require you to rebuild your main toolchain if you have not built it with <code>m4-single</code> support. Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve KOS/Dreamcast support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for Rust's std library using libc support * Create bindings for KOS APIs in the kos-rs crate * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. dad54da0b8b9945095c5e53a824cfbe248b11019 3416 3415 2024-02-10T18:06:39Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve KOS/Dreamcast support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for Rust's std library using libc support * Create bindings for KOS APIs in the kos-rs crate * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. bcf954533e360ad84299cda962df005cd3b1bf92 3417 3416 2024-02-10T18:24:02Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==Future goals== * Evolve KOS/Dreamcast support alongside the maturation of rustc_codegen_gcc * Create implementation for KOS/newlib in libc crate * Create implementation for Rust's std library using libc support * Create bindings for KOS APIs in the kos-rs crate * Integrate Rust-based tooling for disc image handling =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. d4ed1046f8c95dcc37d0fce6755894ff2237f84b 3418 3417 2024-02-12T14:03:21Z Darc 1 /* Future goals */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rust '''kos-rust''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 24c38720c800d0dfdee9dde7f83748cf639aed14 3419 3418 2024-02-12T14:05:12Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 4ce75d1e2be1462ae6476b65fe75b4fc2a51e261 3420 3419 2024-02-12T14:07:51Z Darc 1 /* rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codgen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 1b50be3e621943357812d9e72ed306e1a54ac957 3421 3420 2024-02-12T14:10:20Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc_path</code> file to the location of our <code>libgccjit.so</code> library file: echo /opt/toolchains/dc/rust/sh-elf/lib > /opt/toolchains/dc/rust/rustc_codegen_gcc/gcc_path Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. be13314bde4732399627d85ba1ce2c10d3555d1a 3422 3421 2024-02-13T00:41:25Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file: echo "gcc-path = /opt/toolchains/dc/rust/sh-elf/lib" > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. d1f00e9047b195fa3f50e2bdac748fd9a990fd82 3423 3422 2024-02-13T00:43:06Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== <code>rustc-dc</code> generates <code>.o</code> object files with <code>rustc</code> for inclusion in a KallistiOS <code>Makefile</code>-based project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. bbf2ccaef232db3ac57bdf40fd28a2e06d929caf 3424 3423 2024-02-16T19:56:46Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc Set the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now let's build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. bdf754a467a151964f677f5da5bd69e3e769ffad 3425 3424 2024-02-17T01:34:22Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images =gccrs= '''gccrs''' implements a new Rust compiler frontend for GCC. This essentially means creating a separate new Rust compiler from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. At this point, you should have a shell open to <code>/opt/toolchains/dc/kos/utils/dc-chain</code>. Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 1fb2b8e6b1cd19ea4106815384601f43cc0e073c 3426 3425 2024-02-17T21:23:23Z Darc 1 /* gccrs */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. =rustc_codegen_gcc= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images 40f921d88169041b10f1f3163cc3e984ce432967 3429 3426 2024-02-17T21:30:04Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. Rust is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using them on the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc '''rustc_codegen_gcc'''], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). '''Rust-for-Dreamcast''' includes wrapper scripts to invoke '''rustc''' and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. At this time, there's not yet support for adding new architectures to Rust libraries and tools using '''rustc_codegen_gcc''', and as mentioned before, those tools don't currently support SuperH, so support for customizing build options and proper linking is limited. We will use some workarounds. See the '''rustc_codegen_gcc''' [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build '''rustc_codegen_gcc''' support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4 and you have built KallistiOS with it. See [[Getting Started with Dreamcast development]] for more information. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, '''rustc_codegen_gcc''' will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that KallistiOS doesn't officially support <code>-m4-single</code> yet and so some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images aa64224b9bd7214b82038e17b8e7b76130cdbe1c 3430 3429 2024-02-17T21:45:53Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images f4922566c8f0250fc20678fa40285302a27e9d14 3431 3430 2024-02-17T21:54:32Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal * '''liballoc''' -- the core components of the language that require a heap, including collections * linking to KallistiOS -- KallistiOS can be used if one manually manages interoperating with C via '''unsafe''' '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images 48308bdaba4d3c9a411eb8f4d932abea6b43b9be 3432 3431 2024-02-17T21:58:21Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target in Rust ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images 2f57c500019e102f3c4f6c033b9ca5ca3bac6ada 3433 3432 2024-02-17T22:00:58Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target in Rust ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images 127b818e6f9005360b8cc62d99df4ed361b6c705 3434 3433 2024-02-17T22:02:13Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target in Rust ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images 35d13f5ab82093681155ab00bc9fd7d2c2d98c97 3435 3434 2024-02-17T23:26:31Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target in Rust ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images 6ba08283eeb4fffb4dc967a3179b58d0a799a199 3436 3435 2024-02-17T23:40:01Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target in Rust ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application using <code>cargo</code> * <code>cargo-cube</code> demonstrates how to create a Rust project using KallistiOS and GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images a1547a4776f328f05e16e43d5c17fa6cffc4846c 3437 3436 2024-02-17T23:42:29Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build If all went well, '''rustc_codegen_gcc''' will have built successfully. You'll be able to invoke '''rcg-dc''' to manage the '''rustc_codegen_gcc''' for Dreamcast installation, and you'll be able to invoke '''rustc''' for Dreamcast through a wrapper script command '''rustc-dc''', and likewise with '''cargo''' and its wrapper '''cargo-dc'''. ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application using <code>cargo</code> * <code>cargo-cube</code> demonstrates how to create a Rust project using KallistiOS and GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images c7e22b5c7aa9b2db5703b9b16755b5c7699fec3d 3438 3437 2024-02-17T23:45:39Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application using <code>cargo</code> * <code>cargo-cube</code> demonstrates how to create a Rust project using KallistiOS and GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Compiling individual modules into object files with rustc== To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. ==In-progress/future goals== * Create implementation for KOS/newlib in Rust's <code>libc</code> crate * Create implementation for Rust's <code>std</code> library using libc support * Expand bindings for KOS APIs in the <code>kos-rs</code> crate * Continue to evolve KOS/Dreamcast support alongside the maturation of <code>rustc_codegen_gcc</code> ** Add sh-dreamcast as an official tier 3 Rust target * Expand <code>cargo-dc</code> functionality, including integrating Rust-based disc tools to generate disc images eed859fe821511e0e87f835183f937c5df1b6234 3439 3438 2024-02-18T00:13:01Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''What's Planned''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 850211f8bc583616012c2387cfb4cf35ce831348 3440 3439 2024-02-18T00:15:19Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 7e970921186356d5ca2149b8d58a50eddc3f6a1c 3441 3440 2024-02-18T00:17:23Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 23b297d0530e8f8ce64efaa6690195e988e87364 3444 3441 2024-02-18T13:49:26Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 4f067d94d87e0f99b93f1dfb8ed35fed335fe32f 3445 3444 2024-02-18T14:03:13Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its floating point precision setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. e52c148decc8b3242e40de620d19303d0f8c8b93 3446 3445 2024-02-18T14:06:23Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. a4ea054726fa5416ed276ec725a09b1c2a843969 3447 3446 2024-02-18T14:07:21Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS and any kos-ports being used with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in '''kos-ports''' that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. a6db1cff518795fc87aeadab77b9c3c9580455d7 3448 3447 2024-02-18T14:07:37Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is usable with some patience with limitations and rapid change. '''libcore''' and '''liballoc''' work, and [[KallistiOS]] bindings are planned. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS and any '''kos-ports''' being used with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 9d6c4488ceda01613359ec2b7f3d52863fe567d1 3449 3448 2024-02-18T14:09:05Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS and any '''kos-ports''' being used with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. f9f0d65aa4aad973897fa6bc9e8bfcafc27c50a2 OpenBORManual 0 1314 3403 3272 2024-02-08T17:19:32Z O Ilusionista 167 /* Music & SFX */ wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2027/01/04 - by O Ilusionista''' * Fixed the broken images links * Changed links to Paxplode and Basic Template to Chronocrash. * Fixed information about iconmphigh, iconmphalf and iconmplow =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from ChronoCrash: https://www.chronocrash.com/forum/threads/paxplode-pack.3301/ . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. Also, also controls the level transition fade time. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP any value higher than 2/3 of the max value * This only works for players. Other entities doesn't have MP. Getting 100 mp as an example, it will be same as * - iconmplow: lower than 33 * - iconmphalf: between 33 and 66 * - iconmphigh: higher than 66 (not when full, this is why it appears even if mp is not full) '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is between 1/3 and 2/3 of the max value * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low (1/3 of the max value) * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 617f0b3311fa9bad409035a17fd9d3268c1229a2 3404 3403 2024-02-08T17:20:30Z O Ilusionista 167 wikitext text/x-wiki OpenBoR Guide by Fugue & Bloodbane. Currently updated by O Ilusionista. <span style="color: red;>'''MAJOR WARNING:''' All information contained here was written for version 3 of OpenBOR (up to build 6391).</span> Version 4.0 (build 7530+) of OpenBOR was released with dozens of improvements, but the versions are not compatible with each other - and the PSP port has been officially discontinued. Given the amount of changes, it no longer makes sense to update this manual - except when it is to correct legacy information. You can read more information about OpenBOR 4.0 here https://www.chronocrash.com/forum/resources/openbor.1/updates#resource-update-526 For a more complete manual, I recommend using the Wiki https://chronocrash.com/obor/wiki/ - O Ilusionista, Jan 2024. '''Note to users of older platforms:''' ''Dreamcast, GP2X, and Wiz platforms are officially discontinued since build 4453.'' Therefore, some things may work differently on older ports and any configuration that has a build value greater than 4453 will not work on these platforms. * The latest releases can be downloaded from GitHub: https://github.com/DCurrent/openbor/releases * If you need help on how to start developing for OpenBOR, check this topic: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ '''Last update on 2024/02/08 - by O Ilusionista''' * Added missing information about Custfade affecting the level fade out time too. =General Info= ==Beats of Rage== *Beats of Rage is a semi 3D beat 'em up game made by Senile Team. It is inspired by Streets of Rage series, popular and great semi 3D beat 'em up games by SEGA for Genesis console. However this game uses King of Fighters (a 2D 1vs1 game) sprites as its sprites for heroes and enemies. *As a beat 'em up game, this game has features like combo which performed by tapping attack button after it hits enemy, jump and jumpattacks, SoR2 (Streets of Rage 2) style special, Capcom style grabattacks and SoR2 style throw. There are various enemies in this game, some of them can perform upper attack to hit jumping heroes, some of them can break free from grabs, some of them can grab or throw heroes etc. SoR2 style bikers can also be found here. Of course items like foods and 1Up are also available here. *This great game is also moddable which allows players or modders to modify a mod or even make mods. The method of modding is quite simple cause it's basicly about providing pictures, sprites, wavs and animated gifs and converting them for use in BoR and also setting them with powerful text files (so to speak) for making heroes, enemies, levels etc. In fact, Beats of Rage is actually comprised of Pak and engine (BoR.exe). We could say that Pak is the body while engine is the soul. That's also the reason why mods are usually only in the form of Pak without the engine. *Pak isn't editable (in normal way) that's why before modding, modders need to unpak a mod 1st. After modding is finished, the mod can be packed to be played. Actually it's possible to play a mod without packing but it's best to pak it to make it neat. This great game attracted many players which formed BoR community. *Even though modding is that simple, BoR have many features which have their own usage and their own place (or text to be exact) to declare. This manual is for explaining those features and where they can be declared. *Due to lack of required features from BoR (Beats of Rage) and many requests, some coders stepped in to improve BoR, coded those missing features and fulfilled some requests. There were some BoR variations because of that e.g OpenBoR, DarkBoR and HOR. OpenBoR is the most advanced one and this manual includes OpenBoR features. Actually latest OpenBor support scripts but it's not included here. ---- =Getting Started= *Before you can start modding, you need the ingredients. Most of ingredients are sprites and texts. Due to many required files and complexity of them, it's highly recommended to start modding by editing available game and you can find all the instructions here: https://www.chronocrash.com/forum/resources/how-to-start-on-openbor.311/ ==Extracting an existing PAK File:== * You'll need a program called PAXPLODE.exe. which can be DL-ed from ChronoCrash: https://www.chronocrash.com/forum/threads/paxplode-pack.3301/ . You need to register there 1st before you can DL anything though. * Put this program in same folder with .pak that you want to 'explode'. * Run this command: paxplode.exe [pakname] to 'explode' the pak. [pakname] is the name of .pak file (.pak is included). * If you do it right, a window showing DOS messages about extracting files will appear. * The extracted files should be in same folder in new folder named DATA. * NOTE: Some ppl reported that the files aren't in same folder with Windows XP. If that happens, find folder named DATA in your harddisk. I don't understand why this could happen. It work like I said above in Windows 98SE. *Inside DATA folder, there should be various folders whose name are: BGS, CHARS, LEVELS, MUSIC, SCENES, SOUNDS and SPRITES. Aside from those, there should be text files i.e models.txt, levels.txt, lifebar.txt and video.txt and pal.act. Each text files have their own explanation which will be explained in their own section below. *About the folders, each contains files and texts related to folder name. So BGS contains background pictures and palettes, CHARS contains character's sprites and texts etc. *NOTE: Some folders aren't mandatory meaning you can put all of their files in same folder (still within DATA folder that is) and it would still work (provided the paths are correct). However it's recommended to use different folders like above to make modding easier. You can add another folders if you need to, just make sure the paths are correct. By the way, you can play this paxploded mod! Yes you can! *NOTE 2: Pal.act is global palette, but its not needed anymore (since its encouraged to use 16bit video mode). In the old BOR (or if you use 8bit color mode), this is required - because every sprite in mod must use same palette which is this global palette. You need Adobe Photoshop to view and make .act files. ==Playing paxploded PAK:== * Put bor.exe in same folder as DATA folder (if you are still using old BoR engine). * If you are using OpenBoR, put OpenBoR.exe, every .dll and other folders like LOGS, MENU, PAKS, SAVES and SCREENSHOTS which come with it in same folder as DATA folder. Don't forget to put empty .pak in PAKS folder. You can get empty .pak from BoREdit pack. * No matter which engine you're using, you can play the mod by running the .exe. * NOTE: This is how modders test their mods without packing them. *As for modding itself, what you should do is modifying certain files and make new ones. Since there are many files you might need to modify or make, read the explanation of what each text does below to know what to do with them. *Once you're done and satisfied with your mod, the last step is packing it. ==Creating a PAK File:== * You'll need a program called PACKER.exe. * Put this program in same folder with DATA folder which contains your mod. * Run this command: packer.exe [packfile] DATA. [packfile] is the name of pak you want to create. Actually the DATA can be replaced with other name if you 'DATA' folder has different name but let's use that name. * If you do it right, a window showing DOS messages about packing files will appear. * The .pak should be in same folder. ---- =MODELS.txt:= *This text file determines entities which are loaded and are going to be loaded to the engine. This file is mandatory obviously. Aside from that, this file also determines some general settings for models. *Models.txt must be placed right under DATA folder. *Entities to load are declared with .txt. How to make and modify these texts are described in Entity Files section below. *Order of loaded playable characters in this file also defines the order of them in select screen ==Generic Player Properties== '''ajspecial (bi)''' * Determines the input for special attacks and whether or not players can block attacks. **0 = players use their special with the special key they have assigned and they cannot block. **1 = players can use the input for ATTACKBOTH as a special attack. They can also use a block animation, which will be used when the special attack button is pressed. * If you set 1 but the player does not have a block animation, they can use their special with both the special key and ATTACKBOTH. '''autoland {int}''' * {int} is either 0, 1, or 2, and changes how entities can land after being thrown. **0 (default) = Players can press up and jump when hittting the ground after being thrown by another player or an enemy to land safely. **1 = they can use up and jump for a safe landing when thrown by an enemy, but automatically land safely if thrown by another player. Pits will still be a danger, of course. **2 = players can't use a safe landing at all. '''nocost {bi}''' * Determines how player's special and freespecial attacks costs life. **0 = they always costs life whether they hit something or not **1 = only lose life if they hit something '''nolost {bi}''' * Controls whether or not players will drop the weapon they are holding when grabbing an enemy. ** 0 = players will drop their weapon while grabbing (default). Same result if no value is given. ** 1 = players won't drop their weapon while grabbing. '''noaircancel {int}''' * Sets whether players can cancel their jumpattack with other jumpattacks or not. * In case you don't know, you can cancel a jumpattack by pressing command for other jumpattack. For instance, while performing JUMPATTACK2, pressing attack will cancel the move and player performs JUMPATTACK. **0 = Cancellation is possible (default) **1 = Cancellation is only possible after last jumpattack is finished **2 = Cancellation is not possible at all '''combodelay {int}''' * This command sets interval time between attacks in default combo to perform combo attack by tapping attack button. * Default to 100 which means 50 centiseconds. It means if player press attack button 2 seconds after 1st attack connects, the 2nd attack won't be a combo. However, if it's pressed almost half second later, 2nd attack will be combo * Great to disable cheap infinite combo! '''offscreen_noatk_factor {bi}''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. **0 Means that the entity can attack outside the visible area (default) **1 Means that the entity CAN NOT attack outside the visible area. ==Generic Blocking Properties== '''blockratio {bi}''' * If this is set, blocking will not completely nullify damage. The entity will take one forth of original damage instead '''mpblock {bi}''' * If this is set, damage from blocking will consume MP instead of health. If player is running out of MP, the damage will take health. * blockratio needs to be set before using this. '''nochipdeath {bi}''' * If this is set, entities can't die by blockdamage (damage from blocking). * blockratio needs to be set before using this. * Entities health can be reduced to 1 health with this the next successful blocks won't take any health. '''blockback {bi}''' * Flag to determine if attacks can be blocked from behind. **0 (default) = Entities can not block attacks from behind. **1 = Block attacks are possible ==Select Screen Properties== '''colourselect {bi} {bi}''' * {bi} is a binary value. **0 = you can't change your character's palette. **1 = you can change your character's palette on the select screen by pressing up and down to cycle through the remaps. * If a remap is used for a character's 'fmap' or some remaps are hidden with 'hmap', they will not be selectable. * That's <span style="color: red;>"colour" with a u, not "color"</span>. Some countries spell it different ways. '''spdirection {b1} {b2} {b3} {b4}''' * Sets the facing direction of players in select menu. **0 = facing left. **1 = facing right. * {b1} is for player 1, {b2} is for player 2 and so on. * Default is 1 0 1 0. ==Miscellaneous== '''nodropen''' * Setting this command makes enemies not knocked down on respawn. Normally when player respawns, all enemies onscreen are knocked down (no damage though). * This command doesn't take any argument. Declaring it is enough to set it. '''forcemode {bi}''' * Sets whether the mode specified in models.txt is switchable or not. **0 = the mode can be switched in options menu. **1 = the mode can't be switched {default}. '''versusdamage {bi}''' * Sets whether players can hit each other or not. This overrides options menu. **0 = players can't hit each other. **1 = players can hit each other. '''nocheats {bi}''' * Sets cheat's allowance in this mod **0 = Cheats are allowed **1 = Cheats are forbidden * Those who like fair play should use this ;). '''nodropspawn {bi}''' * When it is on, the spawn position will be restricted to spawn entry setting. '''nodebug {bi}''' * in models.txt. set nodebug 1 to disable debug menu in options ==Attack types & animation limit== <span style="color: red;>If you are receiving an error '' "Invalid animation name line xxx" '', you need to rise the value of the max animations you use for each type.</span> For example, if you have MAXFOLLOWS 4 and try to use FOLLOW10, you will receive that error and you need to change the MAXFOLLOWS to 10. '''No need to change the others''' if you aren't using ''more animations than the max value.'' '''maxattacks {max}''' * Sets the maximum number of normal attacks animation i.e ATTACK1, ATTACK2 etc. * {max} is number of available animations. * Default is 4. '''maxattacktypes {max}''' * Sets the maximum number of attack types. * PAIN,FALL, RISE, BLOCKPAIN and DEATH animations limit is also set together with this. * {max} is number of available types. * Default is 10 & maximum value is 99. '''maxfollows {max}''' * Sets the maximum number of followup animations i.e FOLLOW1, FOLLOW2 etc. * {max} is number of available animations. * Default is 4. '''maxfreespecials {max}''' * Sets the maximum number of free specials. * {max} is number of available free specials. * Default is 8. '''maxidles {max}''' * Sets the maximum number of IDLEs. * {max} is number of available IDLEs. * Default is 1. '''maxwalks {max}''' * Sets the maximum number of WALKs. * {max} is number of available WALKs. * Default is 1. '''maxbackwalks {max}''' * Sets the maximum number of BACKWALKs. * {max} is number of available BACKWALKs. * Default is 1. '''maxups {max}''' * Sets the maximum number of UPs. * {max} is number of available UPs. * Default is 1. '''maxdowns {max}''' * Sets the maximum number of DOWNs. * {max} is number of available DOWNs. * Default is 1. ==Bonus== '''lifescore {int}''' * Determines how many score points players must earn to get one life or 1Up. * Default value is 50000. * Set this to big value to prevent players from getting life from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''credscore {int}''' * Determines how many score points players must earn to get one credit or continue. * Default value is unknown. But by default players won't get credit from score. * Set this to big value to prevent players from getting credit from points. * DO NOT set this to 0 otherwise you'll get crash when hitting enemy. '''nomaxrushreset {int}''' * Determines whether maximum hit counter (max rush) is resetted or not. ** 0 = Max rush is resetted if player loses a life or continue ** 1 = Max rush isn't resetted if player loses a life but still resetted if player continues ** 2 = Max rush isn't resetted if player loses life or continues ==Load & Know== * These 2 commands are used to load entities in OpenBoR. However they don't work the same way, read their description below about it. * Each command loads one entity so that means you have to declare these commands more than once to load many entities. * Any order of these will do but it's recommended to group which ones for flashes, heroes etc. You can give # and comment to describe what each group loads. '''load {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **The entity is always loaded when OpenBoR starts and will always be in memory. **Used for flashes, heros, weapon-holding heros, and hero's projectiles. '''know {name} {path}''' **{name} is a name that the game will use to identify the entity. **{path} is the location relative to OpenBoR of the entity's .txt file. **These entities are only loaded to memory when actually needed or to be exact when levels load them. **Used for everything but flashes and heroes. * You don't need to load music, sound, system, or stage files with these commands. This is used only for entities. ---- =LEVELS.txt - General Settings:= *This text file determines how many game modes (or difficulty in BoR) which are declared in the mod and what levels and scenes each game mode has. This file is mandatory obviously. Aside from that, this file also determines some general general settings for levels and HUD. *Due to lots of features, this part is divided into 2 parts. This part is for general level settings and HUD settings while the other part (Level sets below) is for game modes settings. *Levels.txt must be placed right under DATA folder. ==Fonts== ''(Originally posted by Maggas at lavalit forums)'' In order to create an font you need to known first how to define the size of the font image. That have to do actually with the size of the letters or "letterbox"(see bellow) you want to use. Then if you known size of your letters,then you must multiply the dimensions of your letters x16.(the dimensions are count in pixels) As example,if the size of your letters is width/9 pixels and height/9 pixels,then your font image size have to be width/144 and height/144,or 144x144 in other words. The images bellow can be used as template in order to create your own font. Just pick up which image are fit with your letter dimensions. *'''Font size 144x144 for letters with 9x9 pixels''' This is actually the default BOR font size which is used a lot. This can be used as font,font2,font3 [[File:01 - Font size 144x144 for letters with 9x9 pix.gif]] *'''Font size 160x160 for letters with 10x10 pixels''' This size can be used as font,font2,font3 as well and i think is the maximum size for use as font,font2. [[File:02_-_Font_size_160x160_for_letters_with_10x10_pi.gif]] *'''Font size 192x192 for letters with 12x12 pixels''' This size can be used as font3 [[File:03_-_Font_size_192x192_for_letters_with_12x12_pi.gif]] *'''Font size 208x272 for letters with 13x17 pixels''' This size can be used as font4 [[File:04_-_Font_size_208x272_for_letters_with_13x17_pi.gif]] *'''Font size 256x256 for letters with 16x16 pixels''' This size can be used as font4 [[File:05_-_Font_size_256x256_for_letters_with_16x16_pi.gif]] *'''Font size 272x272 for letters with 17x17 pixels''' This size can be used as font4 and others [[File:06_-_Font_size_272x272_for_letters_with_17x17_pi.gif]] OpenBOR actually can use up to 10 fonts used some commands to define which font is for what and not only 4 fonts. OpenBoR fonts are not monospaced. That is, the space between two letters is determined by how wide the letter is. If your letters 'overlap', try placing a black outline around them, or moving them rightward a few pixels. Here is the "letter format" or just which letters must be used and where to place: <pre>0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ! " # $ % & ´ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; { = } ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ ` a b c d e f g h i j k l m n o p q r s t u v w x y z</pre> * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * <span style="color: red;>Make sure the optional fonts are available before using them!</span> PS: Not all symbols are necessary.You can add which you need. * <span style="color: red;>NUMBERS must be included in font images or openbor will crash without error.</span> * LETTERS are optional. *(for custom fonts) ==Hiscore & Stage complete== '''hiscorebg {bi}''' * If set to 1, the high score screen will have a background. Normally, it's just text on black. '''completebg {bi}''' * Determines whether custom stage complete screen is used or not. **0 = no custom screen is used. A black screen with texts will be shown instead. **1 = custom screen is used. * The custom stage complete screen must be named complete.gif, must be non-animated gif and placed in data/bgs/ folder. '''showcomplete {x1} {y1} {x2} {y2} {x3} {y3}''' * Determines the position of "STAGE # COMPLETE". * <span style="color: gray;>{x1} and {y1}</span> determines "STAGE"'s position. * <span style="color: gray;>{x2} and {y2}</span> determines the number's position. This number shows the completed stage's number. * <span style="color: gray;>{x3} and {y3}</span> determines "COMPLETE"'s position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''clearbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Clear Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Clear Bonus"' position. * <span style="color: gray;>{x1} and {y1}</span> determines Player 1's score bonus' position. * <span style="color: gray;>{x2} and {y2}</span> determines Player 2's score bonus' position. * <span style="color: gray;>{x3} and {y3}</span> determines Player 3's score bonus' position. * <span style="color: gray;>{x4} and {y4}</span> determines Player 4's score bonus' position. * x and y work exactly like they are for 'showcomplete'. * The score will only be shown if the respective player is present when stage completes though. '''lifebonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Lives Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Lives Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for life bonus. '''totalscore {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Total Score" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Total Score"'s position. * <span style="color: gray;>{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for Total Score. '''showrushbonus {int}''' * Determines whether max rush is added as bonus in Stage Complete screen or not. ** 0 = Max rush is not counted ** 1 = Max rush is counted * Make sure you have set 'rush' above before setting this. '''rushbonus {x0} {y0} {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of "Rush Bonus" and its scores for each player. * <span style="color: gray;>{x0} and {y0}</span> determines "Rush Bonus"' position. * <span style="color: gray;>{x1} {y1} {x2}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{x3} {y3} {x4} {y4}</span> works exactly like for 'clearbonus' except that they are for rush bonus. '''scbonuses {stage bonus} {life bonus} {rush bonus} {bonus type}''' * Stand for stage complete bonuses. Determines multiplier value for bonuses in Stage Complete Screen. * <span style="color: gray;>{stage bonus}</span> is stage's bonus. If {bonus type} is set to 1, this become multiplier. Defaults to 10000 * <span style="color: gray;>{life bonus}</span> is life's bonus (lives * life bonus). Defaults to 1000 * <span style="color: gray;>{rush bonus}</span> is max rush bonus (max rush * rush bonus). Defaults to 100 * <span style="color: gray;>{bonus type}</span> determines how {stage bonus} affects. If set to 1, {stage bonus} will be multiplied by current stage's number. This way it will increase as you progress through the mod. See 'stagenumber' in Level Files section below for extra info about stage number. * NOTE: Use multiplies of 10 for {stage bonus}, {life bonus} and {rush bonus}. '''pauseoffset {font0} {font1} {xpos} {ypos} {font_pause} {xpos_pause} {ypos_pause}''' * write "pauseoffset" in levels.txt to change fonts and offset of pause strings. * <span style="color: gray;>{font0} </span>is font index for "continue"/"end game" strings. default 0 * <span style="color: gray;>{font1}</span> is font index for "continue"/"end game" highlighted strings. default 1 * <span style="color: gray;>{xpos}</span> is x position for "continue"/"end game" strings * <span style="color: gray;>{ypos}</span> is y position for "continue"/"end game" strings * <span style="color: gray;>{font_pause}</span> is font index for "PAUSE" string. default 3 * <span style="color: gray;>{xpos_pause}</span> is x position for "PAUSE" string * <span style="color: gray;>{ypos_pause}</span> is y position for "PAUSE" string ==HUD location== [[Image:preview1p.png]] '''p{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's life bar. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''p{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}mp<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's MP bar, if player has MP that is. * Works exactly like p{#}life, except it affects player's MP bar instead. '''p{#}lifex<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player's "x". Which "x"? the "x" between lifebar and number of lives player has that is. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of "x". * {font} determines which font is used for the "x". * Here's font reference for {font}: ** 0 = font.gif (default) ** 1 = font2.gif ** 2 = font3.gif ** 3 = font4.gif ** 4 = font5.gif (optional) ** 5 = font6.gif (optional) ** 6 = font7.gif (optional) ** 7 = font8.gif (optional) (4287+) ** 8 = font6.gif (optional) (4287+) ** 9 = font7.gif (optional) (4287+) * Make sure the optional fonts are available before using them! '''p{#}lifen<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of player 1's current number of lives. In case you haven't figured it out, the number on the right of lifebar is player's lives. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * <span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the number. * {font} determines which font is used for the number. * Font reference is the same as 'p{#}lifex' above. * Default value is 3 or font4.gif. '''p{#}score {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's status. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines player's "-" position. Yes, there is "-" between name and score. * {x3} and {y3} determines player's score position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name, "-" or the score. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}namej {x1} {y1} {x2} {y2} {x3} {y3} {font}''' * Determines the position of player's "Select Hero", Name text, continue, credits and "GAME OVER" when joining the game. * {x1} and {y1} determines player's name position. * {x2} and {y2} determines "Select Hero"'s position. * {x3} and {y3} determines "Press Start"'s position. These also sets "GAME OVER" and credits position. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}shoot<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of weapon's counter when shootnum is used. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the text. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''mp{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of magicbar's icon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''p{#}iconw<span style="color: gray;> {x} {y}</span>''' * Determines the position of player's icon for players with weapon. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}life<span style="color: gray;> {x} {y}</span>''' * Determines the position of the life bar for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the life bar. '''e{#}icon<span style="color: gray;> {x} {y}</span>''' * Determines the position of the icon for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''e{#}name<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{font}''' * Determines the position of the name for the entity which most recently hit/was hit by/touched/interacted with player. Nothing will be shown if that entity hides his/her/its status though. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the name. * {font} determines which font is used for the texts. * Font reference is the same as 'p{#}lifex' above. * Default value is 0 or font.gif. '''p{#}smenu {x1} {y1} {x2} {y2}''' * Determines the position of players in select screen. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines player's position. * {x2} and {y2} determines player's "Ready!" position. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the player's offset (for x1 and y1) or to the top left corner of "Ready!" text. ==HUD settings== http://www.dreamcast-scene.com/uploads/Main/Preview2.p.png '''lbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of lifebars. * This applies to players, enemies, items, etc (their lifebar will all have the same width, height, etc). If 'olbarsize' is declared, this only applies to players. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. **0 (default) = horizontal orientation. Lifebar is filled from left to right in this mode. **1 = vertical orientation. Lifebar is filled from down to up in this mode. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''mpbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls the size of mpbars. * Works exactly like 'lbarsize'. '''olbarsize<span style="color: gray;> {w} {h} </span>{noborder} {type} {orientation} {border} {shadow} {graph} {backfill}''' * Controls opponent's lifebars size. If not available, 'lbarsize' will be used. * Works exactly like 'lbarsize'. '''rush {flag} {duration} {text1} {f1} {f2} {text2} {f3} {f4}''' * This is for showing successful hits counter onscreen. If it is activated, texts will appear onscreen showing how many current consecutive hits and maximum consecutive hits. * As long player hit something, the hit counter will keep incrementing. It doesn't matter if player hit same enemies/obstacles or other ones. Juggling hits also counted. * {flag} is integer value which activates this counter. **0 = counter is off. **1 = counter is on. **2 = counter is on and maximum hits is always displayed. * {duration} sets how long the counter will be on before it expires. * {text1} sets what text to be displayed for hits counter. * {f1} sets which font to be used for {text1}. * {f2} sets which font to be used for hits counter's number. * {text2} sets what text to be displayed for maximum hits. * {f3} sets which font to be used for {text2}. * {f4} sets which font to be used for maximum hit' number. * Here's font reference for {f1}, {f2}, {f3} and {f4} **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif **4 = font5.gif (optional) **5 = font6.gif (optional) **6 = font7.gif (optional) **7 = font8.gif (optional) * Make sure the optional fonts are available before using them! * Don't forget to set 'p{#}rush' below if you set this otherwise it will be piled at topleft corner. '''p{#}rush {x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4}''' * Determines the position of player's 'rush' status. Only effect if you set 'rush' (above) though. Also it's highly recommended to set this too if you set 'rush' otherwise it will be piled at topleft corner. * {#} determines which player this setting is for and its possible values are 1, 2, 3 and 4. There's no space around {#} though. * {x1} and {y1} determines rush text's position. The text for this is modified with 'rush' command above. * {x2} and {y2} determines current rush value position. The font for this is modified with 'rush' command above. * {x3} and {y3} determines max rush text's position. The text for this is modified with 'rush' command above. * {x4} and {y4} determines max rush value position. The font for this is modified with 'rush' command above. * x and y are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of text or value. '''timeloc<span style="color: gray;> {x} {y} {w} {h} </span>{noborder}''' * Controls the position of the clock timer. * To change the font, you'll need to work with the font file, not this command. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>control how far right and down (respectively) the timer is from the top left of the screen. *<span style="color: gray;> {w} </span>and<span style="color: gray;> <span style="color: gray;>{h} </span></span>control the dimensions of the border placed around the timer. If your timer is being displayed under the border or is off-center, try editing this. * {noborder} turns on or off the outline around the timer. {0} means it's there, {1} takes it away. * The default values are 149, 4, 21, 20, and 0, respectively. '''timeicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of timeicon. Timeicon is optional icon that can be place d behind timer to make timer looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''bgicon {path}<span style="color: gray;> {x} {y}</span>''' * Determines the position of background icon. Background icon is optional icon that can be placed behind character's status to make HUD looks cooler ;). * {path} is the location relative to OpenBoR of the icon's .gif. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the number of pixels, right and down respectively, from the top left corner of the screen to the top left corner of the icon. '''scoreformat {flag}''' * {flag} is integer value which controls the align of score text. **0 = Score text is aligned left and unused digits are hidden. **1 = Score text is aligned right and all digits are shown. ==Music & SFX== '''noslowfx {bi}''' * If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays. '''custfade {int}''' * {int} determines how long it takes for music to fade out. Also, also controls the level transition fade time. '''musicoverlap {bi}''' * Determines if the music fades in and out when changing (1), or stops and restarts (0). Defaults to 0. '''noslow {bi}''' * Determines whether or not the level slows down when the boss is defeated. ==Miscellaneous== '''maxplayers {int}''' * Determines how many players could play at same time. * {int} could be 1, 2, 3 or 4. * This setting can be overriden by same command in level sets (see below). '''loadingbg {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while models are being loaded. * The background must be named loading.gif and placed under data/bgs/ folder. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. * {tf} determines used font for "LOADING" text. **0 = font.gif **1 = font2.gif **2 = font3.gif **3 = font4.gif '''loadingbg2 {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while levels are being loaded. * The background must be named loading2.gif and placed under data/bgs/ folder. * The other variables have same effect with 'loadingbg'. '''itemtrans {bi}''' * This makes dropped items transparent. Make sure the items have transparency set before setting this. '''equalairpause {bi}''' * Sets hitpause effect for jumpattacks. **0 = No hitpause **1 = Hitpause in effect ---- =LEVELS.txt - Level Sets= *Just to reiterate, this part is 2nd part of levels.txt section. This part is for game modes settings. ==Header== '''set {name}''' * Marks the start of a difficulty level or game mode. * {name} is the name of the difficulty which will be selectable from the difficulty select menu. '''typemp {int}''' * Controls the conditions under which a player's MP can recover. **0 (or leave blank) = players will recover MP slowly over time. **1 = players will recover some MP when they hit an enemy. **2 = players can't recover MP without using items or dying. '''cansave {int}''' * Defines how save states work in this level set. **0 = Save state is disabled **1 = Only saves last level (Default value). It's buggy currently though. **2 = Strict save. Lives, credits, HP, MP, weapon, remap color etc are saved. When this saved state is loaded, players immediately enter last level without going to select screen. If it's multiplayer game, you will need partner. '''skipselect {name} {name} {name} {name}''' * This command makes select screen and join in selection skipped in current level set. Players will automatically use certain defined player. * {name} is the name of loaded player in models.txt (see above). The 1st one is for 1st player, 2nd for 2nd player and so on. * MAKE SURE the defined player are loaded before using this! * You can empty all values to skip default select screen. However don't forget to set select screen text right after it. * You can set a different player for each level (4287+). Example: <pre> in levels.txt set ... ... skipselect RYU file level1.txt skipselect KEN file level2.txt etc... </pre> '''nosame {b1} {b2}''' *With nosame set, a player can't pick the characters that are currently occupied by other players like some capcom games (for example, Cadillacs and Dinosaurs). For this reason, there's no warning message that tells you don't select the same character. * {b1} Determines whether or not Player 2 and Player 1 can use the same character at the same time. ** 0 (Default)= They can use the same player. ** 1 = They can not use the same player. * {b2} stands for different colourmap select (currently it is not forced). The second flag is for color map index. If active it will skip same map ONLY for same players. Examples <pre> NOSAME 1 NOSAME 1 2 NOSAME 0 2</pre> '''noshare {bi}''' * Determines whether or not Player 2 and Player 1 both use the same credits. If set to 1, each player will have their own supply of credits. '''lives {int}''' * The player will start with {int} lives. '''credits {int}''' * Players will start with {int} credits. * If 'noshare is not set (see above), this will determine total credits for all players. But if 'noshare 1' is set, this will determine how many credits each player has. '''ifcomplete {int}''' * Can be used to create 'locked' levels if {int} is set to 1 or higher. * In the game, OpenBoR will display message on the right side respective game mode like this: Finish the game {int} times to unlock. That means, player must clear a game mode {int} to unlock this game mode. * OpenBoR will save player's progress so no need to do it all at once. * They aren't really secrets, as the players are still be able to see them on the menu, but they won't be able to select it until they've beaten a game mode with defined value. * Characters with 'secret 1' in their header can only be used in difficulty settings with 'ifcomplete'. '''maxplayers {int}''' * Determines how many players could play at same time just for current level set. * {int} could be 1, 2, 3 or 4. * This setting overrides same command in general settings (see above). '''continuescore {int}''' * Determines how taking continue effect score. **1 = score is reset to 0 when you continue. **2 = 1 point is added to your score when you continue. This is to replicate Capcom's scoring system which puts number of continues in their scores. '''disablegameover {int}''' * set 1 you won't display the gameover screen! useful for custom HUD. **0: display (default) **1: not display '''disablehof {int}''' * set 1 you won't display the hall of fame screen! useful for custom HUD. **0: display (default) **1: not display '''noshowcomplete {int}''' * set 1 you won't display the complete screen after NEXT! useful for custom HUD. **0: display (default) **1: not display ==Body== '''z {zmin} {zmax} {BGheight}''' * Changes the location of stage boundaries. * {xmin} is how high up entities can walk. It starts at the top and works down, so larger numbers mean less room. Defaults to 160. * {xmax} is how far down the character can walk. It also goes down from the top. Defaults to 232. * {BGheight} changes where the bottom of the background is drawn. Defaults to 160. By changing this value, you can make the background match an altered {xmin}. * This can be set once per level. You can change it between two stages. If you need to change it during a stage, you should combine it with the "wall" command in the stage itself. * You can spawn entities outside of this range, but once they enter the playing field they can't escape again. '''file {path}''' * This command is for setting levels to play in a 'set'. * {path} is the location of a .txt file which describes a level. * Since this command only sets one level, you may need to declare more of this to set the other levels. * If there are more than one 'file', levels are played from the 1st one to last until there are no more or meet 'end' (see below). * Level to load here is declared with .txt. How to make and modify these texts are described in Level Files section below. '''scene {path}''' * This command is for setting cutscenes to play in a 'set'. * {path} is the location of a .txt file which describes a cutscene. * Since this command only sets one cutscene, you may need to declare more of this to set the other cutscenes. * If there are more than one 'scene', cutscenes are played from the 1st one to last until there are no more or meet 'end' (see below). * Cutscene to load here are declared with .txt. How to make and modify these texts are described in Cutscene Files section below. '''select {path}''' * This command is for setting select screen files to play in a 'set'. * {path} is the location of a .txt file which sets custom select screen. * This can be declared more than once in same game mode and playing order is from the 1st one to last one. * Select screen to load here are declared with .txt. How to make and modify these texts are described in Select Screen Files section below. '''next''' * This command doesn't need any arguments. * When this command is reached, the Stage Complete scene will play, and Scores will be tallied. '''branch {name}''' * Used to give name to warp destination for endlevel entities which uses 'branch'. * {name} is the name of the destination. * Used together with 'branch' feature (see below). '''end''' * When this is reached, the game will end regardless of the levels after it. * There's no point of using 'end' without 'branch' so use this together with 'branch'. ---- =LIFEBAR.txt= *This text file is optional file for setting lifebar colors. This is for OpenBoR only though. *Lifebar.txt must be placed right under DATA folder and tt's lifebar.txt, not lifebars.txt. *{R}, {G} and {B} which are used below are color values from 0 to 255 for Red, Green, and Blue. If you don't know what that means, try thinking of them as brightnesses. If you had 0 255 0, then there would be no red, no blue, and all green, so you'd have green. If you had 0 0 0, there wouldn't be anything, and you'd have black. 255 255 255 would be all of everything, so it'd be white. 255 0 255 would be red + blue = purple. 128 128 128 would be halfway between white and black, so it'd be grey. *If it still doesn't make sense to you, try opening up Microsoft Paint, go to Colors -> Edit Colors -> Define Custom Colors. Try messing around with the Red, Blue, and Green values. It works like that. By the way, setting a color to the transparent color doesn't actually make it transparent. *The color settings must match one of the colors in the default pallete exactly. If your colors aren't correct, try decreasing every color value by 1- some programs report color values to be higher or lower depending on whether they start at 0 or 1. *However, if the mod is using truecolor mode (see video.txt below), all colors defined here will be true RGB colors. Which means, you don't need to check if they are available in global palette or not. '''blackbox {R} {G} {B}''' * Determines the color of the 'shadow' around the lifebar and the bar at 500 health. '''whitebox {R} {G} {B}''' * Determines the color of the outline around the lifebar and the bar at 600 health and up. '''color{#} {R} {G} {B}''' * Determines used color by certain health value. For instance, 'color100' determines used color if health is 100 or less. * There's no space between "color" and {#} in color{#}. * {#} is the health value at which the color will be displayed and its possible values are 25, 50, 100, 200, 300, 400 and 500. * color500 is also used as the background of the lifebar, and is displayed with transparency. * If lifebar is displayed in percentage mode (see 'lbarsize' above for info about it), color reference changes to: **color25 = 0-20% health **color50 = 21-40% health **color100 = 41-60% health **color200 = 61-80% health **color300 = 81-100% health **color400 and color500 aren't used. '''colormagic {R} {G} {B}''' * Controls the color of the MP bar. '''colormagic2 {R} {G} {B}''' * When a player's MP bar is longer than their health, the extra MP is overlaid on top of the first bar in this color, like with health. '''shadowcolor {R} {G} {B}''' * Specify default gfxshadow color. ---- =VIDEO.txt= *This text file is optional file for setting video, widescreen settings and true color mode. Yeah, its function can't be mentioned with just one word. *Just like LIFEBAR.txt, it should be declared in DATA folder. '''colourdepth {int}bit''' * <span style="color: red;>DEPRECATED</span>. All modules are displayed with a 32bit color screen. * This command is for activating true color mode. * Accepted values for {int}bit are 8bit, 16bit and 32bit. Yes, 'bit' must be typed too. * It's 'colour' not 'color'. '''video {int}''' * This command determines what video modes used by this mod. * If you are making long levels whose screen size is 480x240 (widescreen) or you're making high resolution mods, you must use this. * Accepted values are: **0 = 320x240 (default) **1 = 480x272 **2 = 640x480 **3 = 720x480 **4 = 800x480 **5 = 800x600 **6 = 960x540 * This command can't be overriden in OpenBoR menu. '''scenes {path}''' * This command is used to define alternate path for widescreen scenes. * {path} points to folder containing those scenes. Note: defined path must end with slash (/). '''backgrounds {path}''' * This command is used to define alternate path for widescreen backgrounds. * {path} points to folder containing those backgrounds. Note: defined path must end with slash (/). '''levels {file}''' * This command is used to define alternate file for alternate levels.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default levels.txt. * The rule to make alternate levels.txt is the same with making default one. See LEVELS.txt above. '''models {file}''' * This command is used to define alternate file for alternate models.txt. * {file} points to that file. The pointed file must be placed in directly under DATA folder like default models.txt. * The rule to make alternate models.txt is the same with making default one. See MODELS.txt above. ---- =Menu.txt= *This text file is for modifying main menu. Currently there aren't many commands here but more commands will be added in the future. This file is optional. *Menu.txt must be placed right under DATA folder if you're using it. '''renamekey {key} {newname}''' * This command is for renaming key names. Useful and recommended to rename key if it is assigned for functions which is not described by its name. For instance, if 'attack2' is used for blocking, it would be best to rename it to 'block'. * {key} is the key whose name to be changed. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. * {newname} is the new name for the key. Don't forget to use underscore for spaces. '''disablekey {key}''' * This command is for disabling keys. OpenBoR accepts more inputs now but it's possible not all of them are used (including old ones like special and jump) in the mod. It's best to disable not used keys so players won't have to define them. * {key} is the disabled key. Accepted inputs are: moveup, movedown, moveright, moveleft, attack, attack2, attack3, attack4, jump, special, start, screenshot. In case you don't know, those are names of all inputs in OpenBoR. '''fontmonospace {1} {2} {3} {4} {5} {6} {7} {8}''' * This command sets whether font# is monospaced or not. * {1} refers to font.gif, {2} refers to font2.gif and so on. * Accepted values for them are: **0 = Variable width font (default). **1 = Monospaced. ---- =Script.txt= *This text file is for setting number of script variables. Currently there are only 6 commands. This file is optional. *Script.txt must be placed right under DATA folder. '''maxscriptvars {int}''' * Defines maximum number of variables in each script which is accessible by index. * Use 'getscriptvar(index)' and 'setscriptvar(index,value)' to use these variables. '''maxentityvars {int}''' * Defines maximum number of variables in each entity which is accessible by index. * Use 'getentityvar(entity,index)' and 'setentityvar(entity,index,value)' to use these variables. '''maxindexedvars {int}''' * Defines maximum number of global variables which is accessible by index. * Use 'getindexedvar(index)' and 'setindexedvar(index,value)' to use these variables. '''maxglobalvars {int}''' * Defines maximum number of global variables which is accessible by name. * Default value is 2048. * Use 'getglobalvar(name)', 'setglobalvar(name,value)', 'getlocalvar(name)' and 'setlocalvar(name,value)' to use these variables. * <span style="color: red;>If there's no script in the mod, just set it to 0 or don't change it at all unless you know how big it should be.</span> '''alwaysupdate {bi}''' * This command sets when update.c script is run **0 = Only run update.c when game starts **1 = Run update.c anytime including menu, scene, select screen etc * Use this command together with update.c of course '''nocmdcompatible {bi}''' * When nocmdcompatible is enabled, the engine will try to merge @cmd within the same frame, which may not be compatible with old mod, so use with caution. Defaults to 0. * Example: <pre> @cmd f1 @cmd f2 @cmd f3 frame data/chars/ffff/1.gif </pre> * Before: <pre> if(frame==3) { f1(); } if(frame==3) { f2(); } if(frame==3) { f3(); } </pre> * Now: <pre> if(frame==3) { f1(); f2(); f3(); return; } </pre> ---- =Entity Files - Header Data= *This text is for setting characters or entity's stats and animation. Obviously it's mandatory. Due to complexity and lots of features, this part is divided into 3 parts. This part is for entity's stats, 2nd part for animation types and 3rd one for animation settings. 2nd part describes what animations entity must have or could have. *By the way, Damon V. Caskey made a very complete Character Template [http://www.caskeys.com/nwn/forum/media/docs/character_template_001.txt Character Template] listing about any available data. This should help you to get started with your characters. **I've been using this template since starting work on mods, and have updated it gradually as new features came online./ **It saves me a lot of time and hassle keeping my character animations organized, and I figured it might help someone else./ ==Basic Stats== '''name {name}''' * {name} is the name given to the entity by default. * Used for every kind of entities. * It is a string of 1 to 21 characters. You can actually use up to 40 characters, but the name will stretch off the screen or under the timer, making it look silly. You can also make the name even longer than that, but anything past 40 won't be displayed, so you'll really just be making your life harder. * If you really insist on having long name, you will have to reset the HUD display settings like name, score and time to make them displayed properly. See HUD settings in Levels.txt above for info. * OpenBoR will crash on accessing the entity if you try to put a space in the name. You can safely use an underscore (_) instead. * It is mandatory. How would OpenBoR access this entity if there's no name? * Also avoid using same name for different entities, even if they aren't with same type. You would be confused too which one is actually wanted when they are loaded. '''type {type}''' * {type}: **player: The entity is a human-controlled player. **enemy: The entity is a CPU controlled enemy or enemy projectile. **npc: The entity is a CPU controlled ally that will seek out and attack **enemies. The entity is otherwise functionally identical to enemy entities with the chase subtype. You can change the NPC allegiance via hostile setting. Npc types do not count toward groups. **item: The entity is a stationary item which can be picked up. Items can only give one bonus per item. In other words, you can't make one item that both gives 2000 points AND gives a 1-up. **none: The entity is a useless decoration. **steamer: The entity constantly spews the object called Steam upwards with alpha transparency. Default offscreenkill value is 80. **obstacle: The entity is a stationary blockade which can (normally) be destroyed. **text: The entity is a message object. When spawned, it will freeze all objects in play and show it's *IDLE* animation, then dissapear. It can be sped up by pressing attack or jump. Can be used for level intros, mid-level cutscenes, etc. **trap: The entity is an obstacle which cannot be attacked. It can be made to attack, though, and will hit both players and enemies. If a trap is not set up to knock the entity down, the trap will only damage the entity one time. To hit them again, the target entity must take damage from another entity. **endlevel: The entity is an item which, when touched by a player, will end the stage. It can be given a score value to be awarded for level completion. **pshot: The type is outdated and does nothing. You can still use it, but it's ignored. **panel:The entity will scroll together with level. If the entity's speed is 10, entity will stay with panel. If the speed is 5, it will stay with background (for direction left,right and both). This type is used to make multiple layers. '''subtype {type}''' * {type}: **arrow: The entity flies from right to left off the screen. You can use the "flip" command when spawning it to make it fly left-to-right. **noskip: Used with text-type entities. It prohibits the player from using attack or jump to skip through text. **weapon: Used for player weapons which can be picked up and used. **biker: Used for Biker enemies. They fly left and right across the screen and must be knocked off their bikes to be stopped. **notgrab: Does the same thing as the cantgrab command: the entity can't be grabbed. **touch: For items. The item will be collected just by touching it. You won't need to press the attack button. **flydie: For obstacles. When hit, the obstacle will fly horizontally offscreen while playing it's FALL animation. **both: For endlevel items. If there are two players, both must be touching this item to end the stage. **project: For items. When picked up, this entity is treated like a weapon which doesn't actually change any of the character's attributes except for their projectiles. Works for both players and enemies (if they have a GET animation). **chase: For enemies and projectiles. If given to an enemy, he/she will walk towards player all the time. If player is far from the enemy, he/she will run instead. If given to projectile, it will become homing projectile. **follow: For npcs. Will cause an npc to attempt to follow the entity that spawned or summoned it (see below). Uses range setting in *idle* animation to determine how close it will follow. If the npc exceeds the minimum range and no entities it is hostile towards are nearby, it will move to the spawning entity normally. If it exceeds maximum range, the npc will instantly warp to the spawning entity regardless of what it is currently doing and play it’s respawn animation if it has one. An npc without this subtype will behave exactly like an enemy with the chase subtype. It can potentially follow a hostile across the entire level, and will wander randomly if no hostiles are available. **boomerang: The entity you can spawn (with spawnframe for example) with subtype boomerang, will have automatic aimove boomerang and it will active for the owner animations: getboomerang, getboomeranginair. '''health {int}''' * {int} is an integer, a number from -2147483647 to 2147483647 (which also happens to be (2^31)-1, if you're a math fan). * This is the total amount of damage this entity can take before they die. * Do not actually put a boss with 2147483647 health in your game. It's not funny. Seriously! even if there's no time limit, it would be very very boring. * You can use decimal numbers, but it will always round down, so there's no real point. * If you use a value less than one or greater than 2147483647, the enemy starts off dead. Now that IS funny, but not neccessarily useful. * If the number is greater than the width of the life bar, the meter will "double up" the display (if you don't use percantage based lifebar that is). If you don't set lifebar.txt, this can make it hard to tell how much remaining life an entity has. * Not required, but it defaults to zero if it's not there, so that's kind of useless if you don't set it in the level's spawn point. * Used for players, enemies, items, projectiles, obstacles. * For items, this tells you how much life you regain when you pick it up. '''mp {int}''' * {int} is an integer, a number from -2147483647 to 2147483647. * This is the total amount of MP this entity begins with. * MP is drained by attacks set to drain MP. It can be recovered in several ways. * You can use decimal numbers, but it will always round down, so there's no real point. * If the number is greater than the width of the life bar, the meter will "double up" the display. Since the MP bar is already pretty thin, this can make it hard to tell how much MP you have remaining sometimes. * Not required. If a player doesn't have it, they won't have an MP bar displayed. * Used for players and items. * For items, this tells you how much MP you regain when you pick it up. '''speed {int}''' * {int} is a number from 5 to 300. * You can use numbers less than 5, but the entity will still move at the same speed. Same with using more than 300. * Somewhere between 100 and 300, the entity will gain the ability to run off the screen edges and out of the play area, killing it instantly. So that might not be a good idea. * Setting this to 0 will not stop an enemy from moving. You must use 'nomove' to do that. * Used for players, enemies, projectiles, and arrows. * This command doesn't support decimals though. For decimal value, use 'speedf' below. '''speedf {float}''' * Determines entity's speed. * This have same effect with 'speed' but this one allows {int} less than 5 even negative value. * Moreover, decimal values are allowed with this. However its value is 10 times speed's value. For instance, 'speedf 1.5' equals to 'speed 15'. '''running {speed} {height} {length} {move} {land}''' * Determines the character's running abilities. * Used for players and enemies with subtype chase. * If present, players can run by pressing left or right twice and holding the button. The free special attack's input also changes to left, right, attack and right, left, attack. For enemies with subtype chase, this will enable their running ability. * If this is not present, the character will be unable to run. * {speed} is an integer value which works just like speed. * Actually, unlike normal speed, running speed can be greater than 300. Of course, you'd still run off an edge into oblivion if you tried to set a running speed that high. * {height} determines how high a character can jump (if at all) while running. It works like jumpheight. * {length} is an integer value which changes how far a character can jump while running. It is multiplied by the current jump length. * {move} is a binary value. ** 0 = (default) Character stops running if up or down is pressed. Running enemies can't move up or down. ** 1 = Character will continue running if up or down is pressed, but will also move up or down at an angle. Running enemies can move up or down. * {land} is a binary value. 0 means they stop running after landing from a running jump. 1 means they can continue running if the player holds forward during the jump. '''nomove {move} {flip}''' * Used to make a stationary player, enemy or static projectile (one who does not move). For players and enemies, this prohibits them from using WALK animation thus preventing to move. * {move} is a binary value which determines if the enemy can or can't move. ** 0 = Enemy walk with WALK, projectile move normally ** 1 = Enemy doesn't walk at all, projectile stays. Entity speed becomes 0. * NOTE: Even if {move} is set to 1, entity can still be moved with 'move', jumpframe or script. ~By default, enemy adjusts facing direction to face entities they hostile to (opponents). {flip} is a binary value which determines if enemy can turn around to face opponents if the latter stand behind them. ** 0 = Enemy turn around ** 1 = Enemy don't turn around at all * If {flip} is set to 1, enemies will face direction set by 'facing' (see below) or to direction given to them in level texts(See 'flip' command in Level Objects below). * NOTE: Even if {flip} is set to 1, entity can still be flipped with flipframe or script. '''jumpspeed {int}''' * This command determines entity's jump speed. This entity must be able to jump obviously. * This command doesn't support decimals though. For decimal value, use 'jumpspeedf' below. '''jumpspeedf {float}''' * This command determines entity's jump speed. * This command supports decimals. However its value is 10 times jumpspeed's value. For instance, 'jumpspeedf 1.5' equals to 'jumpspeed 15'. '''jumpheight {int}''' * {int} is an integer value which determines how high an entity jumps. * The default value is 4. * An entity's jumpheight also affects how far it flys when knocked down, and how high and far jumpframe moves you. * For Bomb entities, this controls how high the bomb arcs into the air. '''jumpmove {fx} {fz}''' * This allows Player to modify player's jump movement. * {fx} determines effect in x axis: ** 0 = (default) No effect. ** 1 = Left/Right changes facing direction during jump. ** 2 = Left/Right changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. * {fz} determines effect in z axis: ** 0 = (default) No effect. ** 1 = Walking/running momentum is carried during jump. ** 2 = Up/Down changes jumping speed during jump (doesn't work with static jump). ** 3 = Combination of 1 and 2. '''walkoffmove {fx} {fz}''' * This allows Player to modify player's walkoff movement. * it works like jumpmove {fx} {fz} and params are the same meaning. '''turndelay {int}''' * This sets how long the character performs BACKWALK before turning back. * {int} is time in centiseconds. * This is used together with TURN and BACKWALK. '''facing {int}''' * This is for forcing the entity to face certain direction regardless where he/she is going. ** 0 = no force (default). ** 1 = force the entity to face right. ** 2 = force the entity to face left. ** 3 = force the entity to face same direction with level's direction. * Setting this allows players to play BACKWALK. '''chargerate {int}''' * Determines how fast MP recharge with CHARGE animation would be. Default value is 2. '''mprate {int}''' * This sets how many MP player recovers (by time and by hitting enemy) * If typemp = 1, this is the amount MP player recover from hitting enemy. * If typemp = 2, this is the amount MP player recover on regular intervals. '''mpset {mp} {stable type} {stable} {recover rate} {drop rate} {charge rate}''' * This command determines how MP works for this entity. It's combination of many existing features actually but it has new features * {mp} sets maximum MP (just like 'mp' command) * {stable type} sets MP recovery type: ** 0 = Entity continuously recovers mp over time. Default. ** 1 = Entity recovers mp over time, up to value defined by {stable} ** 2 = Entity loses mp over time, down to defined by {stable} ** 3 = Entity recovers mp over time if below value defined by {stable}, and looses mp over time if above defined {stable} ** 4 = Entity starts his/her mp at maximum value, then it will drop steadily to {stable}. After it's reached, the cycle restarts. * {stable} sets stable MP value. Only usable if {stable type} is not set to 0 * {recover rate} sets MP recovery rate * {drop rate} sets MP loss rate * {charge rate} sets MP recharge rate while entity is charging '''edelay {Mode} {Factor} {Cap Min} {Cap Max} {Range Min} {Range Max}''' * Adjusts entity's delay in all animations. Very useful if you want to make Haste or Slow effect ala Dungeon & Dragons without making new models. * {Mode} defines how {factor} is applied to delay. ** 0 = Original delay + {factor} ** 1 = Original delay * {factor} * {Factor} is the value you want to apply to delay. * {Cap Min} is possible shortest delay. * {Cap Max} is possible longest delay. * {Range Min} is the shortest original delay that will be adjusted. Useful to prevent short delays such as 1 centisecond delay to be shortened. * {Range Max} is the longest original delay that will be adjusted. Useful to prevent long delays such as 500 centiseconds delay to be extended. '''nohithead {int}''' * set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 '''backpain {int}''' * set backpain 1 in entity.txt to activate all backpain animations '''summonkill {type}''' * Entity header command. Determines behavior of any sub entities on screen that consider this entity as a Parent if this entity is killed. * {type} * Default: 0 * Behavior type. **0: Do nothing. **1: Kill only sub entities spawned with the Summon command. **2: Kill all sub entities. '''cmd {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> ==Grab & Throw== '''grabdistance {int}''' * {int} determines many things: * How close this entity must be to another to grab it. * How far away this entity will stand while holding an enemy. * How deep this character's attack range is in z axis. This is overriden by 'rangez' and 'attack' (see below). * How close this entity must get to be stopped by obstacles or pick up items. * How close other entities must be to be damaged or blocked by this trap/obstacle. * The default value is 36. '''grabback {bi}''' * If set to 1, when grabbing, this entity will be displayed behind the other entity being grabbed. '''grabfinish {bi}''' * This command determines whether entity's GRAB animation is interruptible or not (see GRAB below). ** 0 = Interruption is possible (default). If enemies use this, they will skip the rest of animation after they knockdown opponent. It's not recommended for enemies. ** 1 = Interruption is not possible. For players, they must wait their GRAB animation to finish before they can perform any grabattacks. For enemies, they'll finish their GRAB animation. * Use this with GRAB animation of course. '''grabwalk {bi}''' * Determines grabwalking speed. If not declared, entity's walking speed will be used instead. * You need to declare GRABWALK to use this obviously. '''grabturn {bi}''' * Determines whether entity can turn around or not when grabbing opponent. ** 0=no turning (default). ** 1=turns around. * If you haven't figure it out, entity turns around if back is pressed while grabbing. Back is opposite of facing direction. * If GRABTURN is available, it will be played while turning. '''cantgrab {bi}''' * {bi} determines whether or not an entity can be grabbed and held (or thrown). * If set to 1, opponent who stand close to this entity will simply pass through. '''paingrab {bi}''' * For enemies. * Determines whether the enemy can be grabbed normally or only in pain animation. ** 0 (default) = enemy can be grabbed normally, if the enemy is grabbable that is. ** 1 = enemy can only be grabbed in pain animation, if the enemy is grabbable that is. '''antigrab {value}''' * This command sets entity's resistance to grabbing attempt by opponent. To grab this entity, opponent's 'grabforce' must equal or more than {value}. * Used in conjuction with 'grabforce'. '''grabforce {value}''' * This command sets entity's power to grab an opponent. This entity will have success grab if opponent's 'antigrab' is equal or less than {value}. * Used in conjuction with 'antigrab'. '''grabflip {value}''' * This command sets how grabber faces grabbed target **1 = Grabber will flip to face target **2 = Target will flip to face grabber **3 = Combination of 1 & 2 (default) * Use this together with grab ability of course '''throwdamage {int}''' * Changes the amount of damage this entity recieves if it gets thrown. * Defaults to 21. '''throw {dist} {height}''' * Controls the angle at which this player or enemy flies if they get thrown. * {dist} is the distance that this entity will fly. * {height} controls how high off the ground this entity will get before it starts falling back down. '''throwframewait {frame}''' * Sets at which frame in character's throwing animation, throwing will start. ==Terrain Interaction== '''height {alt}''' * Affects an entity's ability to walk under platforms. * If the platform is higher off the ground than this entity's height, this entity can move under it. Otherwise, it will get pushed out. However if somehow entity get stuck under platforms which are shorter, entity can only change direction and slide (see Animation Types below). * {alt} is measured from the offset point up. * This setting applies to all animation. If you want certain animations to have different heights use 'animheight' (see Animation Data). '''antigravity {value}''' * This command determines how strong this entity resists gravity. * Value is in percent so setting 100 makes the entity never fall after jumping. '''bounce {bi}''' * Determines whether entity will bounce or not after touches ground after falling. ** 0 = No bounce effect ** 1 = Bounce effect is set '''noquake {b1} {b2}''' * Determines whether or not the screen shakes if the entity hits the ground after being thrown. * {b1} determine if the screen is affected by the shake ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. * {b2} determine if the entity is affect by the shake. Useful to use entities as GUI (graphical user interface). ** 0 = it shakes. Defaults to 0. ** 1 = it doesn't shake. '''no_adjust_base {bi}''' * This command determines how terrain effect entity's base altitude. * Example of terrains are platforms, walls and holes. ** 0 = Terrain can effect entity. Default for most entities. ** 1 = Terrain can't effect entity. Default for arrows. '''subject_to_basemap {bi}''' * This command determines how basemaps effect entity. ** 0 = Basemaps don't have any effect. Default for projectiles. ** 1 = Basemaps have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_wall {bi}''' * This command determines how walls effect entity. ** 0 = Walls don't have any effect. Default for projectiles. ** 1 = Walls have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_hole {bi}''' * This command determines how holes effect entity. ** 0 = Entity can't fall to holes. ** 1 = Entity can fall to holes. Default for most entities. * Aside from above, this command has more effect for enemies. ** 0 = Enemy can walk to holes. ** 1 = Enemy can't walk to holes. Default for most enemies. * For your information, by default enemies can't walk to holes. It's as if holes are walls for enemies. They can jump , fall or move to holes though. '''subject_to_obstacle {bi}''' * This command determines how obstacles effect entity. ** 0 = Obstacles don't have any effect. Default for projectiles. ** 1 = Obstacles have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_platform {bi}''' * This command determines how platform effect entity. ** 0 = Platforms don't have any effect. Default for projectiles. ** 1 = Platforms have effects. Default for most entities. * This should be used by AI controlled entities. '''subject_to_gravity {bi}''' * This command determines how gravity effect entity. ** 0 = Gravity don't have any effect. ** 1 = Gravity have effects. Default for most entities. '''subject_to_screen {bi}''' * This command determines whether entity can move offscreen or not. ** 0 = Entity can move offscreen. Default for non-player entities. ** 1 = Entity can't move offscreen. Default for players. '''subject_to_minz {int}''' * This command toggles minimum Z bounding for entity on field. ** 0 = Entity can move beyond current zmin or minimum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmin or minimum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''subject_to_maxz {int}''' * This command toggles maximum Z bounding for entity on field. ** 0 = Entity can move beyond current zmax or maximum z. Default for panel type entities. ** 1 = Entity can't move beyond current zmax or maximum z. Default for most entities. ** This information was reversed in the manual before January 2019. '''offscreenkill {value}''' * Determines how far an entity could go offscreen before removed or killed instantly. For your information, OpenBoR kills entities which are too far offscreen to reduce number of active entities. * For example, projectiles and arrows are removed automatically by OpenBoR when they are 200 pixels offscreen. Doesn't matter which side they go offscreen to. * In levels which don't allow scrolling back, this is useful to remove unused entities which are left offscreen. However, in levels which allow scrolling back, you might need to set this to avoid entities being killed while you still need it. * {value} is distance in pixels measured from screen edges (left, right, up and down). * Default value for normal entities is 1000, for arrows and projectiles it’s 200 and for bikers it’s 300. Steam default offscreenkill value is 80. ==Entity Interaction== '''aggression {value}''' * For enemies, this command modifies pausetime for enemy before they attack after player is within attack range. * Positive value reduces pausetime making the enemy reacts faster. * Negative value increase pausetime making the enemy reacts slower. '''hitenemy {canhit} {alt}''' * For enemy's projectile entities. * If {canhit} is 1, this entity can hit other enemies, even if they threw this. Obviously, it still can hit players as well. * If {canhit} is 0 or left out, this entity can only hit heros. * If this entity is thrown as a bomb, it won't be able to hit the enemy who threw it until AFTER it explodes. * {alt} determines when this entity can hit other enemies: 0 means it can hit either while in air or on the ground. 1 means the attack can only hit on the ground. '''aimove {type}''' * This command sets enemy's walk AI. IOW it sets how enemy walks around in evels. * Default AI is enemy will go after player or other entity he/she/it is hostile to * Accepted types for {type} are: **Chase = Enemy will always chase player and this allows enemy to use RUN and RUNATTACK if enemy has it. **Chasex = Enemy will chase player but it only lines up enemy's X axis with player's. **Chasez = Enemy will chase player but it only lines up enemy's Z axis with player's. **Avoid = Enemy will always avoid player. **Avoidx = Enemy will always avoid player but enemy only avoids lining up X axis with player's. **Avoidz = Enemy will always avoid player but enemy only avoids lining up Z axis with player's. **Wander = Enemy walks without certain destination (hence the name). **Boomerang = Enemy assume a boomerang moving. ''* Accepted 2nd params for {type} are:'' **Ignoreholes = Enemy walks without ignoring holes. This makes enemy walks to holes stupidly. **Notargetidle = Enemies ignore players when players are in idle animation. * Example: aimove chase notargetidle * Can be declared more than once but combine proper ones. avoid and chase are bad combination but avoidx and chasez are good one '''hostile {type1} {type2} ...''' * Optional. * Specifies what types an AI controlled entity will attack and what entities a projectile with the chase subtype will seek (this does not determine what the entity can hit, only what it will intentionally attack). * Accepted types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you want entity to be hostile to nothing, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be hostile towards. That is to say, an enemy with ‘hostile npc obstacle’ will only attack npc and obstacle types, not players. * Also 'stealth' feature below affect if the entity will target certain other entities or not. '''candamage {type1} {type2} ...''' * Optional. * Specifies what types this entity can hit (very similar to hostile, but determines what entity may hit, not what it will intentionally target). * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit. That is to say, an enemy with ‘candamage npc obstacle’ will be able to hit npc and obstacle types, not players. '''projectilehit {type1} {type2} ...''' * Optional. * Do not let the name confuse you, this is not for projectiles. This setting specifies what types this entity will hit when thrown from a grab. * Available types are enemy, player, npc, obstacle, shot and you can use as many as you need. If you don't want entity to hit anything, just set 'none' here. * Be aware if you use this setting, you must provide all types you wish this entity to be able to hit when thrown. That is to say, an enemy with ‘projectilehit player’ will only hit players when thrown, not other enemies. '''stealth {stealth} {perception}''' * This command sets stealth ability to entity * {stealth} defines how 'invisible' the entity to hostile entities. Default value is 0 * {perception} defines how well entity can see stealth entities. Default value is 0 * For instance, entity with {stealth} 2 is only 'visible' to hostile entities with {perception} 2 or higher * This command doesn't affect visual at all IOW entity is still visible to players '''attackthrottle {rate} {time}''' * rate: chance to cancel attack (must be between 0.0 and 1.0) * time: in seconds, how long should this entity stay tame until next check, the engine will generate a random number between 0 and this value. * note: some action will cancel the timer, for example, getting hit. Seeing the target block or attacking will also affects the timer. A value of 0.5-0.75 should be OK. * the idea is to allow using high aggressive settings to give the AI super quick initial "reflexes" but still enough delay between subsequent attacks to avoid unbeatable cheapness '''boomerangvalues {acceleration} {horizontal_distance}''' * acceleration: the float value for de/acceleration of the boomerang * horizontal_distance: the float value max distance from the spawner and boomerang * speed of boomerang you can set manually (write speed {float}) or by default is 2.0!! ==Palette== '''remap {path1} {path2}''' * Allows you to create alternate palletes for entities. * Each entity can have up to 14 palletes. * {path1} is a sprite of an entity in their normal pallete. {path2} is a sprite of the entity in an alternate pallete. * You should not change the file's pallete. The only changes should be to the pixels in the image, not the pallete data. * Player 2 normally uses the first alternate pallete, but both players can select their color when choosing a character with up and down if the colourselect option is on. * If your entity has sprites with incorrect colors in alternate palletes, the entity may use colors which are not in {path1}. Check the frames with incorrect colors and compare them. Then just add the colors somewhere in {path1} and the new colors in the same position in {path2}. If that sounds confusing, look at K9999's remaps. That's what I mean. * In truecolormode (see video.txt above), this command works same way. '''fmap {int}''' * {int} determines which remap to use by the entity if it gets frozen by an freeze attack (See 'freeze' for more info about freeze attack). * You have to declare that remap with 'remap' before using this obviously. * If hero has 'fmap' set, the respective remap can't be selected at select screen and continue option. * If enemy has 'fmap' set, the respective remap can be used in levels. You might want to avoid using the remap unless you want to see Icemen on your levels. '''palette {path}''' * This is to set default palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as default palette. The {path} is relative to OpenBoR. * If truecolor mode is set but this command is not declared, the 1st image/frame of the entity will be used instead. * Usually used in conjunction with 'alternatepal' below. But sometimes it can be used to change default palette entity is using * If path is set to none, alternate palettes are ignored and allows each frame (see 'frame' in animation data below) to use its own palette * Useful to create effect libraries without having to design public palette for all of those effects '''alternatepal {path}''' * This is to set alternate palette for this entity. ONLY compatible with truecolor mode (see video.txt above)!. * {path} is the location of the image whose palette will be used as alternate palette. The {path} is relative to OpenBoR. * Used in conjunction with 'pallette' above. '''hmap<span style="color: gray;> {a} </span>{b}''' * Hides entity's remap from being selected (in select screen for players). The remaps can still be used with other features, like forcemap or script. * Hidden remaps are from ath remap to bth remap. * For example 'hmap 3 6', hides 3th, 4th, 5th and 6th remap. '''globalmap {int}''' * This command sets independent palette use for mods with 16/32 bit colormode. ** 0 = Entity has it's own palette. ** 1 = Entity uses global palette. '''KOMap {map} {flag}''' * Used to change entity's remap when KO'ed or killed. * {map} is the remap number to be applied. * {flag} determines when exactly remap will be applied: ** 0 = Remap is applied as soon as entity touches the ground ** 1 = Remap is applied at the last frame of last FALL or DEATH animation ==Shadow & Effects== '''shadow {int}''' * {int} is a number from 0 to 6. * Each number corresponds to a specific shadow in the SPRITES folder. * Normally, the lower numbers are smaller. * This determines which shadow graphic will appear centered at this entity's offset point. * 0 means there won't be a shadow. '''aironly {bi}''' * If set to 1, this character's shadow will only be visible when it is off the ground (jumping, falling, etc.) '''gfxshadow {int} {shadowbase}''' * Changes entity's shadow effect. ** 0 = (default) Use generic shadow set. ** 1 = Use entity's current frame for the shadow. Yes, the shadow will be more realistic with this. The angle and length of shadow is defined by 'light' (see below). * {shadowbase} controls how the shadow works in platforms (4287+) ** gfxshadow 1 = default gfxshadow ** gfxshadow 1 0 = default gfxshadow ** gfxshadow 1 1 = no shadow changes on platform/basemap (old builds) ** gfxshadow 1 2 = 2D-like shadow (like platform games) ** gfxshadow 1 3 = combination 1+2 handable via script with new "shadowbase" prop in entityproperty '''alpha {int}''' * If set to 1, this entity will be displayed with alpha transparency. * If set to 2, this entity will use negative alpha transparency (the darker colors are stronger, like shadows). * If set to 3, this entity will overlay transparency. It's described in the engine as being a combination of alpha and negative alpha, and the formula is "bg<128 ? multiply(bg*2,fg) : screen((bg-128)*2,fg)". * If set to 4, this entity will use hardlight transparency. Seems to be the opposite of overlay. The formula is "fg<128 ? multiply(fg*2,bg) : screen((fg-128)*2,bg)". * If set to 5, this entity uses dodge transparency. Described in the code as being "Very nice for a colourful boost of light." * If set to 6, this entity will use 50% transparency. The entire entity will be 50% transparent: every pixel will be averaged with the pixel right behind it. * In 8bit colormode, this setting DOES NOT work with remaps. You need 16bit or 32bit color mode to use this together with remaps. '''parrow {path}<span style="color: gray;> {x} {y}</span>''' * When a player respawns, the image at {path} will flash over the player at {x},<span style="color: gray;>{y} </span>compared to their offset. * The image will be visible for as long as the player is invincible after respawning (determined with makeinv). * I use -48 -130 for mine. You'll probably want yours to be somewhere around there, but I doubt you're using the exact same image and entity, so experiment. '''parrow2 {path}<span style="color: gray;> {x} {y}</span>''' * If player 2 is playing, and respawns, this will appear instead of parrow. You could just use parrow over again, or you could use something to mark that this is Player 2, not Player 1. '''diesound {path}''' * {path} points to a .wav file that plays if the entity is defeated. * It is also played if entity is killed instantly with lifespan or script. '''setlayer {int}''' * This entity will be displayed as if it were at z position {int}, regardless of it's actual position. ==Projectiles== '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally it's used for projectiles but it can be used to load any 'known' entity especially if the entity is never spawned anywhere in level. Useful to load entities which are spawned by commands such as 'throwframe' and 'spawnframe'. * Before using this, the entity must be declared with 'know' in models.txt. '''playshot {name}''' * {name} is the name of an entity. * The player shoots this with pshotframe #. * This does exactly the same thing as a specifying {name} as a knife. Note: As of version 2.0691, playshot is no longer supported. Use knife instead. '''playshotno {name}''' * {name} is the name of an entity. * The player shoots this with 'pshotframe #'. * Difference with 'playshot' is that the shot entity won't fly forward or in other word, it will stay on ground and not moving. That means it can fall to holes. * That also means setting a in 'pshotframe' is useless. '''knife {name}''' * Used like "load". {name} will be thrown like a knife. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Knives can't be used by enemies during a jump. Stars are currently thrown instead. '''boomerang {name}''' * Used like "load". {name} will be thrown like a boomerang. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''star {name}''' * Used like "load". {name} will be flung like a ninja star in a jump. * This command actually causes three stars to be thrown at three different angles. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. * Stars can only be used during a jump. '''bomb {name} pbomb {name}''' * This command is different for players and enemies. Players should use "pbomb" and enemies should use "bomb". * Used like "load". {name} will be tossed out like a grenade. * Bombs start off playing their IDLE animation until one of three things happens: ** 1: The bomb touches an entity ** 2: The bomb is hit by an attack ** 3: The bomb touches the ground * After 1 or 2, the bomb will play it's ATTACK2 animation. * After 3, the bomb will play it's ATTACK1 animation. * After playing it's attack animation, the bomb will disappear. * Bombs are thrown in an arc determined by their speed and their jumpheight. * You'll need to use "load {name} {path}" instead of "know {name} {path}" when declaring the projectile in models.txt. '''rider {name}''' * For ‘subtype biker’ enemies. * {name} should be the name of an enemy in MODELS.txt. * When the bike is attacked, this entity will fall off. * Defaults to “K'” (Yes, with an apostrophe ‘) * If the rider is only loaded with ‘know’ in models.txt, you should add ‘load {name}’ in this biker text to ensure that the ‘rider’ will fall off. * The Rider is spawned at Y+10 from the parent (10 pixels above it). * Rider won’t copy the map from the Biker entity neither there is a way the change it’s palette by native means (until 6931 at least). ==Flash== '''flash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity is hit, not when it hits another entity. * 'noatflash' is required to make this command is activated. '''bflash {name}''' * {name} is the name of flash animation this entity will use. Defaults to "Flash". * This is played when this entity blocks an attack. '''dust {fall} {land} {jump}''' * This command defines what dust entity which will be dropped by this entity on certain conditions below. * Dust is another type of flash which falls instead of floating. To make one, simply make dust animation and declare it in models.txt just like flashes. * {fall} is the dust dropped when entity landed on ground after being knocked down. * {land} is the dust dropped when entity landed after normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * {jump} is the dust dropped when entity jumps with normal jump. Doesn't include animations with 'jumpframe' or script based jumping. * If {fall} is the only one defined, the dust will also be dropped while landing but not while jumping. '''toflip {bi}''' * Used for hitflashes. * If {bi} is 0, this hitflash will always face the same direction when spawned. If set to 1, the hitflash will flip when the attack comes from the other side. '''noatflash {bi}''' * When {bi} is 1, this entity will always play it's personal 'flash' when hit, instead of the attacker's. Useful for obstacles. ==Offense & Defense== '''com {input1} {input2} ... {input15} freespecial{#}''' * Allows you to customize freespecial input commands. * The {#} should be the number of the freespecial you want to change. You can leave it blank for 1 or use 2 though 8 for 2 through 8. There is no space between freespecial and {#}. * If you want to define this command for freespecial9 or higher, make sure 'maxfreespecial' (see models.txt above) has been set. * {input#} defines which key must be pressed. It can be direction or action keys * Accepted direction inputs are: **U: Up **D: Down **F: Forward **B: Back (The direction opposite your current direction. If used, the character will turn around.) * Accepted action inputs are: **A: Attack button **A2: Attack button2 **A3: Attack button3 **A4: Attack button4 **J: Jump button **S: Special attack button **K: Alternate special attack button * You can define same input multiple times if you want to, example: F F A * You can use either S or K for the special attack button commond. You can only use one or the other, so pick one and stick with it. This was done so that modders who use the special key for blocking can remember the key is used to blocK, not use Specials. (B would have been used, for Block, but B is already used for Back.) * Make sure that you don't have any conflicts with other commands. RUN, DODGE, and the directional ATTACKs all have inputs which can be the same as freespecials. * If you use B for {dir1}, flip the next input. The player changes direction, remember? So B, F, A would be 'turn around, move forward, attack', but since you turned around first, moving forward would mean moving in the direction you just turned to. If you wanted to have an input like Street Fighter's Guile or Charlie's Sonic Boom, you'd need to use B, B, A instead of B, F, A. * {input1} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''atchain {number} {number} {number} {number} {number} ...''' * Determines the attack chain order for player. The attack chain only starts if the first attack hits though. Also if player takes too long before pressing attack to combo, the attack chain will reset to 1st. * The maximum length is 12. How they are used are determined by 'combostyle' below. * {number} can be anything from 1 to 12. 1 refers to ATTACK1, 2 to ATTACK2 and so on. Note: before using number 5 to 12, set 'maxattacks' to 12 1st. See 'maxattacks' above. * You can repeat the same number if you need to. * You don't have to use all of them. Setting something like 'atchain 1 3 2' works. * Default combo is 'atchain 1 1 2 3'. '''combostyle {bi}''' * Controls how 'atchain' works. **0 = (Default) Static combo system **1 = Dynamic combo system **2 = Free combo system * With 'combostyle 1', various attack chain can be set with this command. For instance, 'atchain 1 2 5 0 3 3 6 0 4 0' have 3 kinds of attack chain in it. * The attack chains are selected by 'range' specified in respective attack (excluding ATTACK1). In above example, if ATTACK2 can't reach target, attack chain will switch to ATTACK3. If the latter hits, the attack chain becomes '1 3 3 6'. If the latter misses, attack chain will switch to ATTACK4. * With 'combostyle 2', attack chain will be performed even if none of the attacks connects (Streets of Rage 3 style) '''offense {type} {factor}''' * Modifies damage output of given attack type by {factor}. * For example: "offense shock 0.5" will decrease shock attacks to 50%, whereas "offense burn 1.5" will increase burn attacks to 150%. * {factor} could be negative and make the attack give HP instead. For example: -1 makes the attack to give HP to opponent instead of damaging. * Accepted types are: **all (all attacktypes are affected) **normal# (replace # with appropriate attacktype number) **shock **burn **steal **blast **freeze (only affects damage, freeze effect remains) '''defense {type} {factor} {pain} {knockdown} {blockpower} {blockthreshold} {blockratio} {blocktype}''' * Modifies damage received by given attack type by {factor}. * For example: "defense normal3 0.6" will decrease attack3 damage to 60%, whereas "defense blast 1.4" will increase blast damage to 140%. * {factor} could be negative and make the damage restore HP instead. For example: -1 makes the entity regains HP from the respective attack instead being damaged. * Accepted types are exactly sames with 'offense' (see above). * {pain} is for setting 'nopain' (see above) effect just for this {type}. If received damage (with same type) is less than {pain}, entity won't be in PAIN (like nopain) however if damage is higher, entity will play PAIN * {knockdown} works with 'knockdowncount' (see above) and attackbox{#}'s {power} (see Animation Data below). Incoming attack's (with same type) knockdown effect or {power} will be multiplied with {knockdown} before it effects entity. For instance, with 'knockdown = 0.5', it would half knockdown effect from attacks of this type. * {blockpower} works with attack{#}'s {unblockable} (see Animation Data below). If {blockpower} exceeds the latter's value, this entity can block attacks of this type. * {blockthreshold} works just like 'thold' (see above) but just for this type. If received damage (with same type) is higher than {blockthreshold}, entity can't block the attack. * {blockratio} works just like 'blockratio' (see above) but just for this type except that this sets ratio instead. For instance, 'blockratio = 0.5' makes blocked attack (of this type) deals half damage. * {blocktype} works just like 'mpblock' (see above) but just for this type except that this sets which resource will take the damage instead. ** -1 = HP only ** 0 = Use global 'mponly' setting ** 1 = MP then continue to HP if MP reaches 0 ** 2 = Both MP and HP '''blockodds {int}''' * {int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. * 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever. * Enemies can't block during attacks so don't hesitate using this ;). '''thold {int}''' * {int} is the threshold for an entity's blocking ability. * If the entity tries to block an attack with an attack power higher than {int}, they will not be able to do so and will get hit anyway. * If {int} is 0, an entity will have infinite threshold. In other words, they can block any attacks. * Regardless of threshold, if an attack is set to be unblockable, it can't be blocked. '''blockpain {int}''' * Determines how strong entity blocks incoming attack during blocking. * If the attack's damage are lesser than {int}, entity continue blocking however if the damage is bigger or same as {int}, entity plays BLOCKPAIN animation. * Use this with BLOCK animation of course. '''nopassiveblock {bi}''' * Normally when AI controlled entities block a string of attacks, the odds of blocking each incoming hit are always treated separately. With nopassiveblock set to 1, the AI will behave more like a player and hold the block position if hit while blocking a previous attack. * Previous versions of the manual state this property also causes the AI to block "actively", defending itself from attacks that pass close by. This is not true. The AI will never attempt to block an attack that doesn't actually hit. * Obviously entity who use this must have block ability. '''holdblock {int}''' * Determines whether holding special button will make player play his/her block animation once or continuously. ** 0 = (default) Once. Once the block animation is complete, entity returns to idle. ** 1 = Continuously until BLOCKPAIN. Holding special button makes player block continuously (block animation holds at its last frame) until button is released or entity assumes a BLOCKPAIN animation (and while in Blockpain,you are still considered blocking.). Once a BLOCKPAIN completes, entity returns to idle. ** 2 = Continuously. Holding special button makes player block continuously until button is released. After a BLOCKPAIN animation, entity continues to block. * Use this command with block ability of course. Work in conjunction with Blockpain animations. '''guardpoints {int}''' * Defines amount of guardpoints this entity has. * When this entity successfully blocks an attack, guardpoints will be subtracted by that attack's guardcost. * If guardpoints reaches 0, the next block attempt will fail and entity will be forced to play GUARDBREAK animation. The received attack is still blocked though. * Guardpoints will autorecover over time whose recovery time is defined by 'guardrate' below. * This feature works with BLOCK animation and custom blocks with script. '''guardrate {int}''' * Defines recovery rate of 'guardpoints' above. Default value is 2. * Use with 'guardpoints' of course. '''offscreen_noatk_factor {bi} ''' * This command determines the ability of an entity to be able to attack while off screen. Useful to prevent entities that use ranged attacks like shots for example, they can attack without being in the visible area. * 0 Means that the entity can attack outside the visible area (default) * 1 Means that the entity CAN NOT attack outside the visible area. * If set offscreen_noatk_factor in entity.txt it overwrite offscreen_noatk_factor set in models.txt ==Reaction== '''nopain {bi}''' * Used to make the character not playing his/her PAIN animation when hit by a non-knockdown attack. He will continue what he is doing when attacked. '''nodrop {int}''' * Determines entity's resistance to knockdown attacks. ** 0 = Entity can be knocked down (default) ** 1 = Entity can't be knocked down. Can still be knocked down if hit in midair. ** 2 = Entity can't be knocked down even if hit in midair. * This entity will play corresponding PAIN animation if knockdown attack hits him/her/it. For instance, attack3 will make this entity play PAIN3 even if it's a knockdown attack. * Throwing with THROW can still knockdown this entity. * If this entity dies, he/she will play FALL animation or DEATH if it's available and set. '''knockdowncount {int}''' * This setting makes entity more resistent to knockdown attacks. To knock down this entity, either 'attack' with same or higher power than {int} or {int} consecutive knockdown attacks must hit this entity. * If the above requirements is not fulfilled, the entity will play PAIN animation instead if hit by an attack. Played PAIN animation correspond to attacktype that hits the entity. * If {int} = -1, the entity will always be knocked down even if hit by non knockdown attack. '''remove {bi}''' * Only works for projectiles. Defaults to 1. **1 = the projectile will be destroyed when it hits an enemy. **0 = the projectile continues flying even after hitting an enemy. '''escapehits {int}''' * For enemies * If you give this to an enemy, the enemy will perform SPECIAL2 when they get hit by int+1 hits. Don't forget to give the enemy anim SPECIAL2 if you're using this. * In case you haven't figured out, this feature is to make enemy counter attacks after they get certain number of consecutive hits. * The counter will reset if enemy plays any animation EXCEPT IDLE, FAINT and PAIN. The counter works even with grabattacks. '''nodieblink {int}''' * Sets how entity's death animation is played. ** 0 = entity starts blinking as soon as entity die in respective FALL animation. ** 1 = entity won't blink until after the last frame of entity's FALL or DEATH animation when killed. ** 2 = entity won't blink at all during death, and entity will disappear after the last frame of their death animation. ** 3 = entity will play it's death animation without blinking, and will not disappear until scrolled offscreen. The enemy won't count towards 'group's after dying, even though they don't disappear. This setting ONLY works for enemies. '''makeinv {int} {bi}''' * Determines whether or not the character is briefly invincible after being respawned. Otherwise, traps and enemies may be able to attack the player as they reappear- not nice. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking * {int} also controls how long the parrow and parrow2 are visible. * You can also use makeinv in item type entities. This will create an item that gives the player {int} seconds of invincibility , much like a star in Mario. '''falldie {value} or death {value}''' * Determines how DEATH animation will be played when the character dies. ** 0 = fall, blink on ground then disappear without playing DEATH at all (default). ** 1 = No FALL animation, DEATH animation will be played right after final blow ** 2 = Fall first then play DEATH animation. * MAKE SURE that the character have DEATH animation when using this! '''risetime {rise} {riseattack}''' * Model header. Modifies default delay for entity getting up or performing RISEATTACK after being knocked down. The default rise delay is 200, while a RISEATTACK has no delay at all. **{rise} is rising speed. Reduces time in centiseconds of the delay before rising. Use negative values to increase the delay. **{riseattack} is rise attack speed. Reduces time in centiseconds of the delay before a RISEATTACK can be performed. Use a negative value to increase rise time. Speeding up the already instant RISEATTACK may seem pointless, but it can work to counteract a staydown effect. **Example: risetime 0 -50 #appears to be default '''riseattacktype {int}''' * Determines how entity performs RISEATTACK while rising. ** 0 = Only RISEATTACK will be used. Other RISEATTACK animations (see Animation Types below) won't be used. ** 1 = RISEATTACK will be played based on received attacktype. For instance, if entity was knocked down with attack5, entity will perform RISEATTACK5 if it's executed. If required animations aren't available, RISEATTACK will be played instead. ** 3 = Like 1 but if required animations aren't available, RISE will be played instead (no riseattack). '''riseinv {int} {bi}''' * Determines whether or not the player is briefly invincible after rising. * (int) is how many seconds the player will be invincible for. * (bi) is flag which sets blinking ** 0 = Blinking (default) ** 1 = No blinking '''jugglepoints {int}''' * This command limits jugglability of this entity. IOW it controls how many times entity can be juggled. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). * This command is used in conjunction with 'jugglecost' (see Animation Data below). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. * If {int} is set to -1, ''the entity will be immune to juggles.'' '''instantitemdeath {int}''' * This command sets whether the pause when item suicides after being taken is removed or not. ** 0 = pause is not removed. ** 1 = pause is removed. ==Weapons== '''weapons {name1} {name2} {name3} {name4} {name5} {original name}''' * This command sets other model which will be used to replace this entity when a weapon is picked up. * {name#} is the name of the model which this character becomes when they pick up weapon #. # is weapon's number. Don't forget to load the model in models.txt. * {original name} is the name of the character when it doesn't have any weapons equipped. * If {name#} is filled with none, this entity can't pick respective weapon. '''project {name}''' * For subtype "project" items. * {name} is the name of the new projectile the player or enemy who grabs this can use. '''shootnum {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be fired. '''counter {int}''' * For items which can be used as weapons. * This is the maximum number of times a weapon can be dropped before it dissapears forever. * To make weapons hang around basically forever, give them a high value like 100,000 or something. If somebody can drop it that many times, they probably don't deserve to hold onto it! '''reload {int}''' * For items. * If a player picks up an item that has this command, it will restore their ammunition by {int}. * Does nothing if a player doesn't have a weapon. * Should be used with 'shootnum'. * Don't forget that items can only give one bonus. '''typeshot {bi}''' * For weapons. * Determines if the weapon is a gun or a knife. * 0 means a knife, and ammunition will not be displayed, since you can only throw knives once. * 1 means a gun, so ammunition will be displayed. It will also appear on the ground if you run out of ammunition while using it. '''animal {bi}''' * For players with a weapon. * Determines if the weapon is actually an animal to be ridden. * Animals will run away if they are knocked down enough times. * Players on an animal can't be grabbed. '''weaploss {flag} {weapnum}''' * Determines how weapon could be lost when the character is wielding a weapon. ** {flag} 0 (default) = weapon is lost and dropped on any hit. ** {flag} 1 = weapon is lost only on knockdown hit. ** {flag} 2 = weapon is lost only on death. ** {flag} 3 = weapon is lost only when level ends or character is changed during continue. This depends on the level settings and whether players had weapons on start or not. ** {weapnum} is optional. If set on, the entity set weapon to {weapnum} (see weapnum {int}) * This setting can also be declared in weapon text. If you do so, the setting will override similar setting in character's text and it will only be used for that weapon. '''modelflag {int}''' * Determines how weapon model copies animation and weaponlist from original model. ** 0 = Animation and weaponlist are copied ** 1 = Animation aren't copied but weaponlist are still copied ** 3 = Animation and weaponlost aren't copied * Use this with weapon models of course. '''weapnum {int}''' * Used to give number to weapons. {int} is the number. * Declaring this command is important so other command such as 'setweap' (see Level Designs below) could work properly. ==Icon & Lifebar== '''icon {path} {bi}''' * The graphic normally shown next to the entity's life bar. * Normally a 16 x 16 box with a picture of the entity's head. * {path} is the location relative to OpenBoR of the icon's .gif. ~*{bi} controls if the icon will use the entity current palette. Set to 1 to use the same palette. * The position of the graphic can be changed in LEVELS.txt. * You can use a longer image to change the appearence of your character's lifebar, but remember that the box and shadow around it appear on top if you don't turn them off in LEVELS.txt. * Dimensions of the life bar relative to the icon in bbox format (if you haven't changed it in LEVELS.txt): 18 8 103 9 '''iconpain {path}''' * Same as icon, except this appears instead if the entity is being injured. * This only works for players. '''icondie {path}''' * Same as icon, except this appears instead if the entity is dead. * This only works for players. '''iconget {path}''' * Same as icon, except this appears instead if the entity is picking up an item. * This only works for players. Not like anything else has a GET animation. '''iconw {path}''' * For players with a weapon. * {path} should point to a .gif file. * If a player has weapon with a limited number of uses, this icon will appear with a counter for the remaining uses. '''iconmphigh {path}''' * Same as icon, except this appears when the entity's MP any value higher than 2/3 of the max value * This only works for players. Other entities doesn't have MP. Getting 100 mp as an example, it will be same as * - iconmplow: lower than 33 * - iconmphalf: between 33 and 66 * - iconmphigh: higher than 66 (not when full, this is why it appears even if mp is not full) '''iconmphalf {path}''' * Same as icon, except this appears when the entity's MP is between 1/3 and 2/3 of the max value * This only works for players. Other entities doesn't have MP. '''iconmplow {path}''' * Same as icon, except this appears when the entity's MP is low (1/3 of the max value) * This only works for players. Other entities don't have MP. '''nolife {bi}''' * Determines whether or not the player can see the entity's life when they make contact. ** 0 = they CAN see it. Defaults to 0. ** 1 = they CANNOT see it. '''lifebarstatus<span style="color: gray;> {w} </span><span style="color: gray;>{h} </span>{noborder} {type} {orientation} {border} {shadow}''' {graph} {backfill} * This command makes entity's lifebar be displayed onscreen. Usually this is used by bosses but works for any type. * If this is set, entity's lifebar, icon and name will be displayed immediately onscreen. This entity will still shows normal lifebar, icon and name which appears under player's if it interacts with players though. * This settings is not affected by 'nolife' (see above) at all. *<span style="color: gray;> {w} </span>is the maximum amount of health the bar can display. Defaults to 100. *<span style="color: gray;> <span style="color: gray;>{h} </span></span>is the height of the lifebar in pixels. Defaults to 5. * {noborder} turns on or off the border and shadow around life bars. {0} means there is, {1} means no outline or shadow. * {type} is a flag that sets how lifebar show health. 0 (default) means if an entity's health goes over width, the life bar will wrap around and 'double up' on top of itself (1 unit of health is 1 pixel long.). 1 means the lifebar is shown in percent based. * {orientation} is a flag that sets lifebar's orientation. 0 (default) means horizontal while 1 means vertical. * {border} sets layer adjustment of outer border. Default to 0. * {shadow} sets layer adjustment of border shadow. Default to 0. * {graph} sets layer adjustment of graph fill. Default to 0. * {backfill} sets layer adjustment graph background. Default to 0. * The last 4 variables can be used to place lifebar behind player 'icon' or 'bgicon'. To do that you need to give value like -300. '''lifeposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's lifebar onscreen. * It is counted from upperleft corner of screen to lifebar's upperleft corner. * Use this together with 'lifebarstatus' above. '''nameposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's name onscreen. * It is counted from upperleft corner of screen to name's upperleft corner. * Use this together with 'lifebarstatus' above. '''iconposition<span style="color: gray;> {x} {y}</span>''' * This command determines display position of entity's icon onscreen. * It is counted from upperleft corner of screen to icon's upperleft corner. * Use this together with 'lifebarstatus' above. ==Miscellaneous== '''credit {int}''' * For items. * If an item has this set, it will give player credit when player take it. * Keep in mind that only one bonus can be given to an item. '''secret {bi} {int}''' * Used to make a 'secret' character who must be unlocked before he/she can be played * {bi} defines where secret character can be played: **0 = Can be played in any level set **1 = Can only be played in locked level set or level set with 'ifcomplete' in it (see levels.txt above) * {int} defines how many times game must be completed before the character is unlocked * Even though secret character is locked, you must load him/her with 'load' command instead of 'know' (see models.txt above) '''sleepwait {value}''' * Determines how long player must stand still in IDLE animation before SLEEP animation is played in centiseconds. Default value is 10 seconds. '''score {onkill} {multiplier}''' * Changes the score earned by killing this entity. Both {onkill} and {multiplier} are {int}s. * When the entity dies, the player who killed him/her/it will get {onkill} bonus points to their score. * Any hits landed on this entity by a player which would increase the player's score is multiplied by {multiplier}. * The default value is 5 for the multiplier. Setting {multiplier} to 0 makes it use default setting. Use -1 if you want to set 0 multiplier. * When used with an item, {onkill} changes the amount of score added when the item is picked up and {multiplier} is not used. '''smartbomb (power) (type) (pause) (length}''' * This is for players. Enemies use the 'bomb' command for something else. Don't mix the two up! * If this is present, the player's special will work differently: it will become a "smart bomb" which damages all onscreen enemies, regardless of position. * {power} is an integer value which determines attack damage. * {type} is the attack's effect type: ** 0 = knockdown1 (based on attack1) ** 1 = knockdown2 (based on attack2) ** 2 = knockdown3 (based on attack3) ** 3 = knockdown4 (based on attack4) ** 4 = blast ** 5 = burn ** 6 = freeze ** 7 = shock ** 8 = steal * {pause} is a binary value which determines whether or not all action onscreen pauses when you use your special. Used for a dramatic effect. * If {type} was set to 6 (freeze), {length} can be used to determine how long the enemies will remain frozen. * This command can also be used for items. In this way you can make "smart bomb" items to clear the screen. If you do use it with an item, {length} will replace {pause} * Exactly what is so smart about a bomb that just hits everything, anyway? '''branch {name}''' * This is used to make endlevel entity warps players to certain level instead of the next level in a level set if player touch it. * {name} is name of the destination in a level set. * In case you haven't figure it out, this feature is to make branch for multiple paths. '''lifespan {value}''' * Sets entity's lifespan after the entity is spawned. {value} is in seconds and it supports decimals. * After {value} expires, entity will die and will play entity's death animation if the entity has it. * Entity who uses this can die normally if {value} hasn't expired of course. '''scroll {value}''' * Used to make non panel typed entities scroll like panel type. * {value} is in decimals. =Animation Types= *Just to reiterate, this part is 2nd part of entity files section. This part is for animations types entity must have and could have. *Also, all animation types below (mandatory or optional) can't be declared more than once. If there were 2 or more animations with same name, the last one would be used and the formers are ignored when that animation is called. ==Non Attack== '''WAITING (used for players)''' * An optional animation. * Plays on the character select screen when a character is highlighted (that is, pressing an attack button will select them). '''SELECT (used for players)''' * An optional animation. * Played when you select a character on the character selection screen (that is, you've pressed an attack button to indicate you want to use this character). '''SPAWN (used by all entities)''' * An optional animation. * Plays when an entity appears in a level, whether from the level's .txt file or being respawned after dying. It also plays on the character select screen. * For players, this is only played when they are spawned to level for 1st time. * It generally beats having new enemies just fall from the sky. That looks kind of silly with most enemies. '''RESPAWN (used by all entities)''' * An optional animation. * For enemies, this does the exact same thing as SPAWN. You can use them interchangeably. * For players, this is only played when they are respawned to level after losing life. '''IDLE (used by all entities)''' * The animation for entity when he/she/it is just standing there. Well that's the easy way to describe it. * Technically, this animation is played when entity isn't doing anything and not in any condition (aside from idle). Entity could move in this animation though. * If the SELECT and SPAWN graphics are not present, the IDLE animation will be used instead in select screen. * Entity can have more IDLE animations, see below. '''IDLE# (used by all entities)''' * Played if there's opponent within set 'range' while in IDLE. * # is the number of animation. Do not type # but type a number instead. * For instance, IDLE2 has 'range 0 100'. Entity will play default IDLE when enemy is farther than 100 pixels but once an enemy is within 100 pixels, IDLE2 will be played instead. * If there are multiple IDLE# animations, the one with lowest number has the highest priority. * Before using this, increase the maximum number of IDLE with 'maxidles' in models.txt (see Models.txt above). * These animation ARE NOT related to PAIN#, FALL# or DEATH# at all! '''FAINT (players, enemies)''' * Optional. * If this animation is present, whenever this entity's health is 1/4 (one quarter) or less than it's maximum health, it will use this animation instead of it's IDLE animation. '''SLEEP {players}''' * Optional. * It will be played if player does not move at all for certain time. That certain time is set with 'sleepwait' command. * If it is not looped, player will return to IDLE animation when it is finished. If it is looped, player will continously play it until player moves. * It will be overridden by FAINT, if FAINT is available too. '''WALK (players, enemies, projectiles)''' * Optional for non-moving enemies. They won't use it, so why give it to them? * The animation for an entity walking left or right. * If a character does not have UP and DOWN animations, they will use this instead when walking up or down. * Projectiles only use this if they are homing projectiles. For this purpose, 'range' is supported. * Entity can have more WALK animations, see below. '''WALK#''' * Played if there's opponent within set 'range' while in WALK. * Works just like IDLE# above except it's for WALK. * Before using this, increase the maximum number of WALK with 'maxwalks' in models.txt (see Models.txt above). '''WALKOFF {players, enemies}''' * Optional * This animation is played when entity walks off platforms or walls * WALK animation usually won't look good when entity is falling while walking so use this animation too to make entity look better :) '''BACKWALK {players, enemies}''' * Optional. * Players play this only if they have 'facing' set. * Enemies will play this if they move backwards while facing players. * Entity can have more BACKWALK animations, see below. '''BACKWALK#''' * Played if there's opponent within set 'range' while in BACKWALK. * Works just like IDLE# above except it's for BACKWALK. * Before using this, increase the maximum number of BACKWALK with 'maxbackwalks' in models.txt (see Models.txt above). '''TURN''' * Optional. * For players and enemies. * This animation will be played when players or enemies turn back after walking backwards with BACKWALK. '''UP {players, enemies}''' * Optional. * Played when the character walk up, up-left, or up-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more UP animations, see below. '''UP#''' * Played if there's opponent within set 'range' while in UP. * Works just like IDLE# above except it's for UP. * Before using this, increase the maximum number of UP with 'maxups' in models.txt (see Models.txt above). '''DOWN {players, enemies}''' * Optional. * Played when the character walk down, down-left, or down-right. * For this animation to work correctly, it must have the same number of frames as the WALK animation. * Entity can have more DOWN animations, see below. '''DOWN#''' * Played if there's opponent within set 'range' while in DOWN. * Works just like IDLE# above except it's for DOWN. * Before using this, increase the maximum number of DOWN with 'maxdowns' in models.txt (see Models.txt above). '''DUCK {players, enemies}''' * Optional. * This will only play in a stage whose max and min 'z' are the same (In other words, a 2-D stage). * Plays when a player presses down. They can use this to duck under high attacks. * This animation is also played if player is under platform which is shorter than his/her height. However in this state, player is forced to play this animation instead. In this state, pressing left or right only changes direction. * While ducking, player can perform either SLIDE or DUCKATTACK (see below). * If DUCKING is present (see below), this animation will play after it. * For enemy that use DUCK you can use "range {min} {max}" animation command for custom DUCK when the entity is in that custom range. '''DUCKING {players, enemies} (6330+)''' * Optional. * This animation occurs before the "DUCK" animation. In other words, it's a transition between the idle and the duck animation. * After this animation ends, the entity will go to DUCK if the hold button is held. * Same rules of DUCK appliess here. '''DUCKRISE {players, enemies} (6330+)''' * Optional. * This animation occurs after the "DUCK" animation if the down button is not being held. In other words, it's a transition between the DUCK and the IDLE animation. * Same rules of DUCK appliess here. '''LAND (players)''' * Optional, but players may still be able to land safely depending on the 'autoland'settings in MODELS.txt. * If a player is thrown by an enemy (Thrown, not knocked down), then they can press Up and Jump right when they hit the ground to recover instantly and take no damage. This animation will be played instead of the normal fall animation. '''RUN (players, enemies)''' * Optional. * If the player has their running speed specified, this is the animation they will use to run. * To perform this, tap forward twice then hold forward to keep running. * By setting loop to 0 and adding in the jumpframe command, you can turn this into a dash animation. The player will leap forward. * This animation is only used by enemies with subtype chase. Their running speed is determined by 'running' or 'speed' if that's unavailable. '''BACKRUN (players, enemies)''' * Optional.(4310+) * To active it set facing {flag} at entity header. * Using back,back or forward,forward (in opposite direction) you'll enter in backrun '''JUMP {players, enemies}''' * Plays when a player presses jump or when an enemy approaches a platform. * You don't need to draw the entity moving upward, since BoR moves them automatically. * If given to an enemy, this animation should also have a range listed. * Every jump animations including this will keep playing until the character lands regardless how long the animations are. '''JUMPDELAY {players, enemies}''' * Optional. * Played just before entity jumps with normal jump. Used to make delay animation before entity actually jumps. That means when this animation is played, entity is still on ground. * It won't be used if entity jumps with 'jumpframe'. '''JUMPLAND {players, enemies}''' * Optional. * Played after entity lands from normal jump. * It won't be used if entity jumps with 'jumpframe'. '''FORWARDJUMP {players, enemies}''' * Optional. * Played when entity jumps forward with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''RUNJUMP (players)''' * Optional. * Played when entity jumps forward while running with normal jump. * It won't be used if entity jumps with 'jumpframe'. '''DODGE (players)''' * Optional. * Players with this animation can perform a 'depth' dodge up or down by pressing up or down twice. * The player will move along the z axis (closer to or farther from the screen). * The dodge will last as long as the animation does, and you can't cancel out of it by attacking. So don't set it to loop. * This cannot be used with ATTACKUP, ATTACKDOWN, or freespecials with the input U, U or D, D. '''GET {players, enemies}''' * Optional. * Played when the character picks up an item. '''JUMPCANT {players}''' * Optional. * This animation is only played if player tried to perform jumpattack which costs energy without having enough energy. '''CHARGE {players}''' * Optional. * Despite its name, this animation is not related to CHARGEATTACK at all. * This animation is executed by holding special and jump together. As long the buttons are held, the animation will play continuously. * While playing, player's MP will be recovered at specified rate. The recharge rate is specified with 'chargerate' (see Entity's Header data above). '''CANT (players)''' * Used with MP. * If a player has this animation, and they attempt to use an attack which costs more MP than they have at the moment, they will play this animation and can't dodge or attack until it ends. * If the attack they were using had the Special button as input, they will block instead of playing this animation. '''GRAB {players, enemies}''' * Optional for enemies and players. * When this entity moves close enough to another, this entity will grab hold of the other. * If a player grabs an enemy, they can hold the direction opposite the enemy for a few seconds to let go and walk away. * If you don't want this entity to be able to grab, just don't give them this animation. '''GRABWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks while grabbing enemy. * The grabwalk speed is determined by 'grabwalk' (see above). However, declaring this animation is enough to enable grabwalking. * This animation is like WALK animation so setting 'loop 1' is recommended. However, this animation is NOT performed in reverse while walking backwards. Use GRABBACKWALK below for that case. '''GRABBACKWALK (players)''' * Optional. Currently only used by players. * This animation is played when player walks backwards while grabbing enemy. Only played if player can't turn around while grabbing. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKUP (players)''' * Optional. * This animation is played when player walks upwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABWALKDOWN (players)''' * Optional. * This animation is played when player walks downwards (in z axis that is) while grabbing enemy. * The grabbackwalk speed is also determined by 'grabwalk' (see above). * This animation is like WALK animation so setting 'loop 1' is recommended. '''GRABTURN (players)''' * Optional. * This animation is played when player turns around while grabbing enemy. Only usable if 'grabturn' is set to 1. * During this animation, player is stationary even if player can perform GRABWALK. OTOH grabbed opponent will be moved to opposite place with same grabdistance. '''SLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while walking or idling or in WALK or IDLE animation. '''RUNSLIDE {players}''' * Optional. * This animation is performed by pressing DOWN+JUMP while running or in RUN animation. '''EDGE {players} (6330+)''' * Optional. * This animation is played when the player is on the edge of walls, platforms and holes, as if trying to balance so as not to fall. '''BACKEDGE {players} (6330+)''' * Optional. * Works like EDGE animation, but happens when the edge is behind of the player. '''VICTORY {players} (6330+)''' * Optional. * This animation is performed when you defeat all bosses in a level. '''LOSE {players} (6330+)''' * Optional. * This animation is performed when you got a time over. ==Attack== '''ATTACK1 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * An attack. Players perform this by pressing attack (unless the chain order is changed). * Enemies perform this attack when a player is in range (range is specified with the 'range' command). * Enemies are slightly more likely to use ATTACK1 than ATTACK2. * Enemy bombs play this animation if they touch the ground. If they don't have an ATTACK2 animation, they'll use this instead, as well. '''ATTACK2 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * Another attack. Players use this if they press attack after hitting with ATTACK1 twice (unless the chain order is changed). * Enemies use this just like ATTACK1. * Enemies are slightly more likely to use ATTACK2 than ATTACK3. * Enemy bombs play this animation if they touch another entity's bbox or attack box. '''ATTACK3 {players, enemies}''' * By default, this animation is NOT optional for players. It is optional for enemies. * And another attack. Players use this if they press attack after hitting with ATTACK2 (unless the chain order is changed) * This animation is also played instead if grab finishers and chargeattack are not available.. * Enemies use this just like ATTACK1 and ATTACK2. '''ATTACK4 {players, enemies}''' * Optional. * Players use this only if it is included in 'atchain' . * Enemies use this just like ATTACK1, ATTACK2 and ATTACK3. '''ATTACK5,ATTACK6,... {player,enemies}''' * These animations are only usable if you have increased ATTACK animations limit. To increase the limit use 'maxattacks' (see details above in Models.txt section). * After they are available, they work just like ATTACK1, ATTACK2, ATTACK3 and ATTACK4. '''CHARGEATTACK {players}''' * Optional. * This attack is unleashed after holding attack button for about 3 seconds then let it go. * If this is not available, the last attack in player's attack chain will be played instead. '''ATTACKBOTH {players}''' * Optional. * An attack. Players use this if they hold attack and then press jump. * This cannot be used if the player has a BLOCK animation. If MODELS.txt has 'ajspecial 1', this is replaced by the special attack. '''UPPER {enemies}''' * Optional. * If a player is on the same row as an enemy with an UPPER animation and jumps, the enemy will perform this attack automatically. * Range command (see Animation Data below) can be used for this attack although it's not necessary. '''RUNATTACK {players}''' * Optional. * Requires the character to be able to run. Otherwise, they can't really use it. * If the player presses attack while running, they will perform this attack. * Although player is running while attack is pressed, player won't be moving in this animation. If you want them to move, insert 'move' here. '''RUNJUMPATTACK {players}''' * Optional. * Requires the character has a RUN animation. Otherwise, they can't really use it. * If the player presses attack during a running jump, they will perform this attack. '''JUMPATTACK {players, enemies}''' * An attack. * For players, this is the attack performed when a player jumps and presses attack. * Enemies randomnly perform this attack when a player is in range. * The jump is automatic. You don't need to use the jumpframe command or draw the entity moving forward. * When enemies use this attack, they'll jump forward. '''JUMPFORWARD {players}''' * Optional. * If a player has this animation, they will only play their JUMPATTACK animation if they jump straight up and attack. This attack will be used if they jump forward and attack. '''JUMPATTACK2 {players, enemies}''' * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the down button and pressing attack. * Enemies randomnly perform this attack when a player is in range. * When enemies use this attack, they'll jump straight up. '''JUMPATTACK3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then holding the up button and pressing attack. '''JUMPSPECIAL/SPECIAL3 {players}''' * Optional. * An attack. Just like the normal JUMPATTACK, except that players perform this attack by jumping, then pressing special. * Unlike other jumpattack animations, players lost their momentum in this animation. IOW they won't move up and forward at all even if they are running before jumping. They still fall normally of course. The only exception is if 'dive' is present in the animation. * This animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''ATTACKUP {players}''' * Optional. * An attack. Players perform this by pressing up twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Up, Up, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKDOWN {players}''' * Optional. * An attack. Players perform this by pressing down twice. * This attack overrides freespecials. If you use it, you will not be able to use a freespecial which has Down, Down, {button} as it's input. You also can't use this attack if you use the DODGE animation. '''ATTACKFORWARD {players}''' * Optional. * An attack. Players perform this by pressing forward twice. * This attack cannot be used with running. Also, if you use it, you will not be able to use a freespecial which has Forward, Forward, {button} as it's input. '''ATTACKBACKWARD {players}''' * Optional. * An attack. Players perform this by pressing backwards once, then quickly pressing attack. * Unlike most attacks which use the back button, this does not flip your direction. '''FOLLOW{#} {players,enemies}''' * Optional. * {#} is number and its accepted values are 1, 2, 3 and 4. There's no space between FOLLOW and {#}. * It works just like any attack animation except that it is only played when followup condition is met or entity is attacked in counter pose. '''FOLLOW5,FOLLOW6,... {player,enemies}''' * These animations are only usable if you have increased FOLLOW animations limit. To increase the limit use 'maxfollows' (see details above in Models.txt section). * After they are available, they work just like FOLLOW1, FOLLOW2, FOLLOW3 and FOLLOW4. '''FREESPECIAL{#} {players, enemies}''' * Optional. * If {#} is not placed on the end of the name, it references FREESPECIAL1. If {#} is a number from 2 to 8, it references that FREESPECIAL. Anything else is an error. * There is no space between FREESPECIAL and {#}. * An attack. The input depends on the 'com {dir1} {dir2} {action} freespecial{#}' earlier in the .txt file. * FREESPECIAL defaults to F, F, A if you can't run and B, F, A if you can. FREESPECIAL2 defaults to D, D, A. FREESPECIAL3 defaults to U, U, A. The other FREESPECIALs don't default to anything, and thus need to be defined to be useable by command. * For enemies, this animation works just like normal attack animations. '''FREESPECIAL9,FREESPECIAL10,... {player,enemies}''' * These animations are only usable if you have increased FREESPECIAL animations limit. To increase the limit use 'maxfreespecials' (see details above in Models.txt section). * After they are available, they work just like other FREESPECIALs. '''SPECIAL {players, enemies}''' * Optional for enemies. * A breakout attack. * Players perform this by pressing special. They can use it while being held by an enemy to break free, or while playing an injured animation (besides fall, shock, burn, and death) to counterattack. * For players to use this attack, they must have at least 6 life, which they will lose upon performing the attack. You can change this with 'energycost' (see below). * Enemies perform this attack automatically if a player grabs and holds them for too long without throwing them or knocking them down. However, they'd lose 6 health too after performing this move just like players. Use 'energycost' to modify it. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''SPECIAL2 {players, enemies}''' * Optional. * Players perform this by pressing forward and special, or special while running. * Enemies perform this after they receive certain number of consecutive hits. Used together with 'escapehits'. * For players, this animation can be disabled with 'type' in level texts. See 'Level files' below for more info '''GRABATTACK {players, enemies}''' * Optional for enemies, can be made optional for players with cantgrab or notgrab. * When you've grabbed another character, you can press attack to use this attack up to two times. '''GRABATTACK2 {players, enemies}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABATTACK twice, you can press attack to use this attack. * You can also use this early by pressing jump. '''GRABFORWARD {players}''' * Optional. * When you've grabbed another character, you can press forward and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABFORWARD2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABFORWARD twice, you can press forward and attack to use this attack. * You can't use this early by pressing jump and forward. '''GRABUP {players}''' * Optional. * When you've grabbed another character, you can press up and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABUP2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABUP twice, you can press up and attack to use this attack. * You can't use this early by pressing jump and up. '''GRABDOWN {players}''' * Optional. * When you've grabbed another character, you can press down and attack to use this attack up to two times. Just like GRABATTACK except for the input. '''GRABDOWN2 {players}''' * Optional. If not defined, defaults to ATTACK3. * When you've grabbed another character and used GRABDOWN twice, you can press down and attack to use this attack. * You can't use this early by pressing jump and down. '''THROW {players, enemies}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack. * By default, this animation deals 21 damage to the thrown victim. You can change the height, distance, and damage recieved for the throwee with the 'throwdamage' and 'throw' commands. * The normal score rules do not apply to throws: they always reward the thrower with a number of points equal to the damage they dealt. * The damage from this attack is not dealt until the victim lands. If they are a player and have a LAND animation, they can recover by pressing Up and Jump right when they land and avoid damage completely! '''GRABBACKWARD {players}''' * Optional. * When you've grabbed another character, you can press back and attack to use this attack up to two times. Just like GRABATTACK except for the input. * Since it has same command as THROW, don't use them both to avoid confusion! '''GRABBACKWARD2 {players}''' * Optional. * When you've grabbed another character and used GRABBACKWARD twice, you can press back and attack to use this attack. * You can't use this early by pressing jump and back. * Since it has same command as THROW, don't use them both to avoid confusion! '''DUCKATTACK {player}''' * Optional. * This animation is performed if attack is pressed while player is ducking. * It can also be played when player is forced to duck like under platform. ==Reaction== '''PAIN{#} {players, enemies}''' * Played when an entity is hit by an attack which does not knock them down. Bikers play this as their death animation. * {#} determines the number of PAIN animation. The possible numbers are 2 to 10 and empty. There's no space between PAIN and {#}. Empty means just PAIN without number. * This animation is used in conjuction with attack{#}. Example: PAIN5 will be played if entity is hit by non knockdown attack5. * PAIN is mandatory while PAIN2, PAIN3 etc are optional. * If required PAIN{#} is not available, PAIN will be used instead. * This animation will also be played if entity is hit by knockdown attack but entity is immune to knockdown attack with 'nodrop' or 'knockdowncount' (see them in Header Data above). Number of PAIN animation will be determined by received attack number. '''PAIN11,PAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other PAINs. '''BACKPAIN{#} {players, enemies}''' * Played when an entity is hit from behind by an attack which does not knock them down. * {#} determines the number of BACKPAIN animation. The possible numbers are 2 to 10 and empty. There's no space between BACKPAIN and {#}. Empty means just BACKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BACKPAIN5 will be played if entity is hit by non knockdown attack5. * To enable this, you need to add BACKPAIN 1 to entity header '''SPAIN {players, enemies}''' * Optional. Defaults to PAIN. * No, not Spain. It stand for Shocked PAIN. * Played when an entity is hit by a shock attack which does not knock them down. '''BPAIN {players, enemies}''' * Optional. Defaults to PAIN. * This means Burned PAIN. * Played when an entity is hit by a burn attack which does not knock them down. '''FALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack. * {#} determines the number of FALL animation. The accepted numbers are 2 to 10 and empty. There's no space between FALL and {#}. Empty means just FALL without number. * This animation is used in conjuction with attack{#}. Example: FALL3 will be played if entity is hit by knockdown attack3. * FALL is mandatory while FALL2, FALL3 etc are optional. * If required FALL{#} is not available, FALL will be used instead. * Declaring 'bbox' in this animation allows entity to be juggled. * Entities can't be grabbed (by walking to them) in this animation. * This animation will also be played if entity is knocked down by non knock down attack such as hit while in air or while frozen or entity uses 'knockdowncount -1' (see it in Header Data above). Number of FALL animation will be determined by received attack number. '''FALL11,FALL12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other FALLs. '''BACKFALL{#} {players, enemies, obstacles}''' * Played when an entity is knocked down by a knock down attack from behind. * To enable this, you need to add BACKPAIN 1 to entity header * Follow the same logic of FALL animation '''RISE{#} {players, enemies}''' * Played when an entity who has fallen down gets back up normally after being knocked down or thrown. However, entities could play RISEATTACK instead of this if certain conditions are met (see RISEATTACK below). * {#} determines the number of RISE animation. The accepted numbers are 2 to 10 and empty. There's no space between RISE and {#}. Empty means just RISE without number. * This animation is used in conjuction with attack{#}. Example: RISE2 will be played if entity was falling in FALL2 animation before. * RISE is mandatory while RISE2, RISE3 etc are optional. * If required RISE{#} is not available, RISE will be used instead. '''RISE11,RISE12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEs. '''RISEB {players, enemies}''' * Optional. * Played when an entity is rising after falling with BURN animation. '''RISES {players, enemies}''' * Optional. * Played when an entity is rising after falling with SHOCK animation. '''BACKRISE{#}, BACKRISEB, BACKRISES, BACKRISEB, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK{#} {players, enemies}''' * Optional. * Players play this instead of RISE if Up+Attack is pressed before they rise. * Enemies play this immediately if a player is in range of the attack while they are lying on ground. * {#} determines the number of RISEATTACK animation. The accepted numbers are 2 to 10 and empty. There's no space between RISEATTACK and {#}. Empty means just RISEATTACK without number. * This animation is used in conjuction with attack{#}. Example: RISEATTACK2 will be played if entity was knocked down with attack2 before. * How entity performs RISEATTACK is controlled by 'riseattacktype' in Header Data above. '''BACKRISEATTACK{#}, BACKRISEATTACKB, BACKRISEATTACKS {players, enemies}''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations '''RISEATTACK11,RISEATTACK12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other RISEATTACKs. '''RISEATTACKB {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with burn attack before. '''RISEATTACKS {players, enemies}''' * Optional. * Played when an entity is riseattacking after knocked down with shock attack before. '''SHOCK {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a shock attack which knocks them down, or a shock attack while in air or frozen. '''BACKBPAIN, BACKSPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during pain '''BACKBURN, BACKSHOCK, BACKBURNPAIN, BACKSHOCKPAIN''' * Played when an entity is hit from behind by an attack with entity header with backpain 1 and attacked by forcedirection 0 (default) * Respective backpain animations for burn/shock during fall '''BURN {players, enemies}''' * Optional. Defaults to FALL. * Played when an entity is hit by a burn attack which knocks them down, or a burn attack while in air or frozen. '''DEATH{#} {players, enemies, obstacles}''' * Optional. Although it is optional, DEATH will be used as default if other DEATH{#} aren't available. * Played when an entity loses all it's life after hit by attack{#}. Example: DEATH8 will be played if entity is killed by attack8. * How this animation will be played is controlled by 'falldie/death' (see Header Data above). * {#} determines the number of death animation. The accepted numbers are 2 to 10 and empty. There's no space between DEATH and {#}. Empty means just DEATH without number. * If an entity is killed by being thrown, they will not use this animation. '''DEATH11,DEATH12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other DEATHs. '''BACKDEATH{#} {players, enemies, obstacles}''' * To enable this, you need to add BACKPAIN 1 to entity header * Played when an entity loses all it's life after hit by attack{#}. Example: BACKDEATH8 will be played if entity is killed by attack8. * Follow the same logic of DEATH '''BDIE {players, enemies}''' * Optional. * Played when the character is finished by 'burn'. * It's still controlled by 'death' though. '''SDIE {players, enemies}''' * Optional. * Played when the character is finished by 'shock'. * It's still controlled by 'death' though. '''CHIPDEATH {players}''' * Optional. * Played when players are killed by chip damage while blocking. 'blockratio' must be set before using this and don't set 'nochipdeath' (see them in Models.txt section above). ~For your information, chip damage is reduced damage from attacks recieved while blocking. '''BLOCK (enemies, players)''' * Optional. * For players, this animation will only play if 'ajspecial 1' is in MODELS.txt. It will play when the player presses the special attack button. * Enemies use this with 'blockodds {int}'. If an enemy blocks your attack, they will play this animation. * Enemies will only block an attack if it would otherwise hit them (i.e. they won't block an attack which goes 10 feet over their heads). * Also, only attacks from front would be blocked. Attacks from behind won't be blocked even if they are blockable. '''BLOCKPAIN{#} {players,enemies}''' * Optional. * Used together with 'blockpain' (see Header Data above). Played if received damage exceeds 'blockpain' while blocking. * {#} determines the number of BLOCKPAIN animation. The accepted numbers are 2 to 10 and empty. There's no space between BLOCKPAIN and {#}. Empty means just BLOCKPAIN without number. * This animation is used in conjuction with attack{#}. Example: BLOCKPAIN7 will be played if entity is hit by attack7. * If required BLOCKPAIN{#} is not available, BLOCKPAIN will be used instead. If BLOCKPAIN is also unavailable, BLOCK animation will be replayed. '''BLOCKPAIN11,BLOCKPAIN12,... {player,enemies}''' * These animations are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other BLOCKPAINs. '''BLOCKPAINB {players, enemies}''' * Optional. * Played when an entity received too much damage from 'burn' attack while blocking. '''BLOCKPAINS {players, enemies}''' * Optional. * Played when an entity received too much damage from 'shock' attack while blocking. '''GUARDBREAK {players, enemies}''' * Optional. * Played if entity blocks an attack but his/her 'guardpoints' is 0. See 'guardpoints' in Header Data above. '''GRABBED {players, enemies}''' * Optional. Defaults to the PAIN animation if not present. * Plays when this character is grabbed by another. '''GRABBEDWALK (players,enemies)''' * Optional. Although only players who can perform GRABWALK, other players (aside from enemies) can be grabbed too. * This animation is played when entity is being held and grabbing player is grabwalking. '''GRABBEDBACKWALK (players,enemies)''' * Optional. I hope the name doesn't confuse you. * This animation is played when entity is being held and grabbing player is grabbackwalking or walking backwards while grabwalking. '''GRABBEDWALKUP (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking upwards (in z axis that is) while grabwalking. '''GRABBEDWALKDOWN (players,enemies)''' * Optional. If the name confuses you, try reading it slowly. * This animation is played when entity is being held and grabbing player is walking downwards (in z axis that is) while grabwalking. '''GRABBEDTURN (players,enemies)''' * Optional. * This animation is played when entity is being held and grabbing player is grabturning. '''HITWALL (players,enemies)''' * Optional. * This animation is played when entity hits a wall while falling. '''HITPLATFORM (players,enemies)''' * Optional. * This animation is played when entity hits a platform while falling. '''HITOBSTACLE (players,enemies)''' * Optional. * This animation is played when entity hits an obstacle while falling. ---- =Animation Data= Just to reiterate, this part is 3rd part of entity files section. This part is for animation's settings. Animation Headers are commands which can only be declared once per animation. Frame properties are commands which can be declared more than once in animation. With the exception of 'frame', they must be declared BEFORE respective 'frame' and can only be done once. "Frame" commands are commands which can only be declared once per animation however they have frame parameter to define at which frame they work. Related commands are here too. Attack supplement are commands which should be declared together with 'attack{#}' and typed between 'attack{#}' and 'frame'. They also work with 'blast', 'steal', 'burn', 'shock' and 'freeze'. ==Animation Header== '''@include''' * With this tag, you can import another animation text file to the current animation (build 3842+). * For example, save below as "data/chars/a/walk.txt": <pre> anim walk delay 5 bbox 0 0 20 60 frame data/chars/a/1 frame data/chars/a/2 frame data/chars/a/3 frame data/chars/a/4 frame data/chars/a/5 </pre> * Them call this file using @inlcude: <pre> anim walk @include data/chars/a/walk.txt anim idle @include data/chars/a/walk.txt anim follow1 @include data/chars/a/walk.txt</pre> '''loop {bi} {start} {end}''' * Determines how loop effect is applied in current animation * {bi} toggles looping on or off. ** 0 = looping off ** 1 = looping on * {start} determines the number of frame the animation loops to. Defaults to 0 or 1st frame. * {end} determines the number of frame which starts the loop. If left blank, the animation will loop at the end of animation. * Some animations should NOT be set to loop (loop temporary at least). Examples include most attacks and injured animations. '''fastattack {bi}''' * Normally, in order for an attack to hit entities multiple times, the attack boxes must be separated by at least one frame with an empty attack box (one set to all 0) and must also be separated by a brief delay. * If this is set to 1, this animation's attack boxes are not restricted by the delay (it will still need an empty attack box between frames, though). '''blockfx {path}''' * {path} should point to a .wav file. * If during this animation entity blocks an attack, this sound effect will be played. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). * Defaults to block.wav but if that sfx isn't exist, beat1.wav will be used instead. '''blockflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If during this animation entity blocks an attack, this blockflash will be played instead of the normal hitflash for this entity. Normally used in BLOCK animation but it works in any animation if entity is in blocking status (set by script). '''bflash {name} ''' * {name} is the name of an entity declared in MODELS.txt. * Does the same of above. blockflash command is old and coded before bflash. '''range {min} {max}''' * Used for AI controlled entities' attacks and jump. Usually used by enemy, NPC and homing projectile. * This command lets the entities know when to perform their attacks or to jump on platforms. * For the entity to use the attack, its opponent must be more than {min} away, but less than {max} away in x axis. * Entity's opponent is determined by 'hostile' setting (see Header Data above). * For the enemy to jump on a platform, the enemy must be within {min} pixels of the platform, and the platform must be less than {max} pixels high. * This is measured in pixels, starting at the entity's offset point and moving towards the opponent's offset. * If not included, the first number will default to -10, and the second to 20 times the entity's jumpheight variable. * For homing projectiles, this determines their targeting range. * If this command is declared together with 'rangez' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. * Default 'range' for ATTACK{#} is 0 75, for JUMPATTACK and JUMPATTACK2 is 0 150, for UPPER -10 120 and for BLOCK is 1 100. The last one only has effect if enemy uses 'nopassiveblock'. * Use it into GETBOOMERANG or GETBOOMERANGINAIR to get the boomerang by range '''rangez {min} {max}''' * This command works similar with 'range' (see above) except that it works in z axis instead. * Default values for {min} and {max} are '-grabdistance/3' and 'grabdistance/3' respectively. * If this command is declared together with 'range' and/or 'rangea', opponent's location must be within ALL of them before attack animation is performed. '''rangea {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis or altitude instead. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with 'range' and/or 'rangez', opponent's location must be within ALL of them before attack animation is performed. '''rangeb {min} {max}''' * This command works similar with 'range' (see above) except that it works in y axis and detects opponent's base instead. * Unlike 'rangea', it only detects base instead of altitude. Opponent's altitude will be ignored. * Default values for {min} and {max} are -1000 and 1000 respectively. * If this command is declared together with other range commands above, opponent's location must be within ALL of them before attack animation is performed. '''dive {hori} {vert}''' * Allows characters to dive while in air. So obviously, they need to be in the air for it to work. * Actually this command simply makes entity moves downwards so it works even on ground. However, it's buggy cause entity will be stuck. * NOTE: Animations with this ALWAYS starts diving at the first frame. If you want to change starting frame, you gonna need script. * {hori} controls how fast the diving entity will move forward, horizontally. * {vert} controls how fast the diving entity will move downward, vertically. * This command is outdated. Use 'jumpframe' below for better effect. '''energycost {int} {mponly} {disable}''' * Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations. * {mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command below. * {disable} controls entities which can't use animation in which this command is declared. Useful to use same weapon models for players, NPCs and enemies with special abilities limitation. ** 0 = None (default). Every entity can use this animation ** 1 = All entities ** 2 = Enemies and NPCs ** 3 = Players and NPCs ** 4 = Players and Enemies * When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on several factors: * If the player has enough MP to use the attack, it comes from their MP. * If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to 'mponly', their MP will be drained and the anything left will be taken from HP. * If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health. * This command also work with enemies. Since enemies don't have MP, this command will only drain health. * If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT animation, they will play that instead. * Defaults to 6 for SPECIAL and 0 for anything else. '''mponly {int}''' * Controls where this attack drains it's energycost from. ** 0 = it will come first from MP, then from HP if there isn't enough. ** 1 = this attack will only drain MP. ** 2 = this attack will only drain HP. '''mpcost {int}''' * When the attack is performed, (int) will be subtracted from the player's MP. * <span style="color: red;>This command is outdated </span> and supported only for the sake of modders who already were using it. If you haven't use this, use "energycost" above! '''followanim {value}''' * Determines which FOLLOW animation played when followup condition is met or when counter condition is met. * Possible values are 1, 2, 3 and 4. * Used together with 'followcond' or 'counterframe'. '''followcond {value}''' * This command is to make the entity performs FOLLOW{#} if an attackbox in the animation hits. * value determines the condition requirements before FOLLOW{#} is played. ** 1 = this animation will followup as long as it hits an entity. ** 2 = this animation will followup as long as it hits an enemy (Or player if an enemy uses it). ** 3 = this animation will followup as long as it hits an enemy and the target does not get killed or not block the attack. ** 4 = this animation will followup as long as it hits an enemy, and the target is not killed, does not block the attack, and is not set to be ungrabbable. ** 5 = this animation will followup as long as it hits an enemy and the target does not get killed or block the attack. * Which FOLLOW animation played is determined by 'followanim'. '''attackone {bi}''' * This command sets attackboxes's ability in the animation to hit other opponent. ** 0 = attackboxes can hit all opponents. This is default setting for all animations but grabattacks ** 1 = attackboxes can only hit one opponent. This is default setting for all grabattacks. '''counterattack {bi}''' * If set to 1, attackboxes in this animation will also hit opponent's attackbox. However, this only works if opponent has active bbox when he/she is attacking. * Like the name sais, this is great for counter attacks. '''bouncefactor {r}''' * This command determines bounce effect after touching ground while falling to ground. It works even if entity is falling while playing non-FALL animation. * {r} is bounce ratio which controls bounce effect. If it's set to 1, entity will bounce forever. If it's set to 2, it will bounce longer than normal. Any bigger value has slight difference. * Normally this is used in FALL animation however it also works with other animations. * This command won't have any effect if 'bounce' (see above) is set to 0. '''animheight {alt}''' * This command sets entity's height just for this animation. It overrides 'height' (see Header Data above) if it's declared. * Defaults to 0 or 'height' if it's not declared. '''cancel {start frame} {end frame} {hits} {sequence of inputs} {freespecial#}''' * This command allows animation change by inputting sequence of inputs to certain freespecial. In other word, cancel. Obviously it's only for players. * This command can be declared in any attack animations, jump animations and grab animations. Also it can be declared more than once in same animation for various cancels. * {start frame} and {end frame} defines frames where sequence of inputs is accepted. Inputs entered before {start frame} and after {end frame} will be ignored. * {hits} defines how many hits attackboxes in this animation must hit before cancelling is allowed. It doesn't matter whether the attacks are blocked or not. If you don't want to have this limit, just set it to 0. * {sequence of inputs} defines input sequence required to activate the freespecial. The accepted values here is exactly same with 'com' command in Entity Files: Header Date above. * {freespecial#} defines the freespecial to be played after input sequence is valid. Don't forget to set 'maxfreespecials' (see models.txt above) if you need more freespecials to access. * Technically, the animation cancelling is like this: when valid sequence is accepted, this animation will stop immediately and defined freespecial will be played. * If 'cancel' is declared in jump animation, the freespecial will subject to gravity and will end immediately when player landed like any jump animations. * If 'cancel' is declared in grab animation, grabbed enemy will be freed IOW player is not in grabbing state anymore. * If you declare 'cancel' in GRAB for player who also has GRABWALK, declare it in latter animation too so the input is received even if player is grabwalking. Same goes with GRABBACKWALK. * Be careful in using single button input cause engine can easily accept the input when this animation is played. For example, cancel with just attack button as input in GRABATTACK will make cancel activated immediately as soon as it's played. To avoid this, set {start frame} late enough for engine to remove the input which activated GRABATTACK. * {sequence of inputs} now accepts "+" to add mutiple commands. Examples: <pre> a + a2 u + f a u + f -> a "->" symbol useful just for better reading </pre> '''chargetime {int}''' * Determines how long player must hold attack button before releasing it to unleash CHARGEATTACK. * {int} is time in seconds. * ONLY works in CHARGEATTACK animation. '''sync''' * Using sync {animation name} will make the two animation synchronize with each other. For exmpale, in a horse riding stage, you can make idle and walk switch seamlessly, with delay timer inherited. * Example: <pre> anim idle sync walk .... anim walk #sync walk # this can be optional since it is already anim walk</pre> =="Frame" Commands== '''pshotframe {frame} {a}''' * If this command is present, the player will fire it's 'pshot' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The shot is defined by using the 'playshot' command. *<span style="color: gray;> {a} </span>defaults to 70. * This command is outdated since all entities including players can use throwframe for same purpose. '''throwframe {frame} {a}''' * If this command is present, the entity will throw it's 'star' or 'knife' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. Since you can't use 0 for {a}, if you want to have the projectile on the ground (and thus able to fall into pits it crosses) use -1 instead. It will spawn at 0, not -1. * The projectile is defined by using the 'star' or 'knife' commands. * Actually putting 'load star' or 'load knife' in the .txt file works also but it's only loads projectile named 'star' and 'knife' respectively. *<span style="color: gray;> {a} </span>defaults to 70. * Knives will be used if the entity is on the ground. Three stars will be used if the entity is airborne. * If you want entity to throw knives while entity is airborne use 'shootframe' instead. '''shootframe {frame} {a}''' * This command is similar to 'throwframe' but it shoots 'shot' instead. *<span style="color: gray;> {a} </span>defaults to 0. * This command won't throw stars if entity is airborne so it's ideal for shooting knives while airborne. '''custknife {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'knife' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Knives can't be used by enemies during a jump. '''custboomerang {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'boomerang' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! * Use throwframe command to throw a boomerang with custboomerang command or just use subentity {name} and spawnframe command '''custstar {name}''' * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the enemy's default 'star' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''tossframe {frame} {a}''' * These 2 commands have same function but only "tossframe" which works for players and enemies. * If this command is present, the entity will throw it's 'bomb' once frame {frame} is reached. * The projectile will be spawned at altitude {a}. * The projectile is defined by putting 'load bomb' in the .txt file, or using the 'bomb', 'pbomb', 'custbomb', or 'custpbomb' command. *<span style="color: gray;> {a} </span>defaults to 70. '''custbomb {name} / custpbomb {name}''' * Use "custbomb" for enemies and "custpbomb" for players. * {name} is the name of an entity declared in MODELS.txt. * If present, for this animation only, the entity's default 'bomb' entity will be replaced with this entity. * You still need to fire the entity at some point in the animation for this to do anything. * Don't forget to load the entity in MODELS.txt! '''jumpframe {frame} {speedy} {speedx} {speedz} {dust}''' * If this command is present, the entity will perform a jump once frame {frame} is reached. * {speedy} is jumping velocity, {speedx} is x axis velocity and {speedz} is z axis velocity. Positive {speedy} value moves entity up, positive {speedx} moves entity front while positive {speedz} moves entity down in z axis. Negative value works the opposite. * {dust} defines which dust entity this entity will drop when entity jumps. See 'dust' command above for more info about dust entity. * For reference, the speed is x1pixel/centisecond for all 3 speed. For instance, if speedx is set to 2, entity will move 2 pixels/centisecond forward. * Despite its name, this command can be used to make entity moves straight instead of jumping by setting {speedy} to 0. It can also be used to make entity dives by setting negative {speedy}. * With {speedy} set to 0 and {speedx}/{speedz} set, entity will stop automatically at the end of animation. * Only one jumpframe command counts. Entity can't jump more than once in an animation by putting more in, even if the entity lands before the next jump starts. To set double or more jumps within same animations, script is required. * Now this command gives same effect to all entities. However there are default setting left behind for backwards compatibility. If {speedx} and {speedz} are not provided this is how the jump would be: **SpeedY is 0: ***Player: The jump is very low, but the character moves forward. ***Enemy: The jump is high and vertical. **SpeedY > 0: ***Player: The jump is {speedy} high, and vertical. ***Enemy: The jump is {speedy} high, and moves forward. *If you don't want that effect, simply give the desired value for {speedx} or just 0. * Setting 'jumpframe' in any FALL animation will change the respective falling arc. Useful to make launchers and custom throws. '''dropframe {frame}''' * This is used to make entity switch to set {frame} when flight apex is reached while in air. '''landframe {frame} {dust}''' * If this is set, entity will be forced to frame {frame} when entity lands after jumping with 'jumpframe' or while falling no matter which frame entity currently is. * {dust} defines which dust entity this entity will drop when entity lands. See 'dust' command above for more info about dust entity. * In order to get this to work properly, give long delay to frame right before landing frame. The former frame will be played while 'waiting' to land. * Make sure the landing frame exists otherwise the entity will disappear right after landing! '''flipframe {frame}''' * Used to make character turn around when frame+1 is played. * Management is not responsible for any damage caused of using this command in improper animation such as WALK. '''quakeframe {frame} {loops} {intensity}''' * Used to make screen shakes with certain intensity. * {frame} determines at which frame the quake/shake starts. * {loops} determines how many quake this animation will make after quake starts. Bear in mind that if the animation ends, there won't be another quake. And you have to provide a frame for each quake. * {intensity} determines how strong the quake would be. Technically it is how far the panel would go down in pixels. * Negative value works for this and the quake will be new style extreme quake. '''counterframe {frame} {cond} {damaged}''' *'''This command is outdated and only included for backward compatibility. Use Counterrange instead (see bellow).''' *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *cond determines the condition requirements before FOLLOW{#} is played. *1: The counter will always be used. *2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). *3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. damaged determines whether the entity will receive damage from the hit or not. *0, the damage won't be taken *1, the damage will be taken '''counterrange {start} {end} {condition} {damage}''' *Animation header. If all conditions are met, entity will perform animation set by followanim. *This command is to make entity performs FOLLOW{#} if the entity is hit in set frame. *frame determines at which frame if entity is hit , FOLLOW{#} would be played. *Which FOLLOW animation played is determined by 'followanim'. *{start} Start of frame range when counter may trigger. *{end} End of frame range when counter may trigger. *cond determines the condition requirements before FOLLOW{#} is played. **1: The counter will always be used. **2: The counter will be used as long as the attacker was an enemy (Or a player if an enemy uses it). **3: The counter will be used as long as the attacker was an enemy, the attack was not unblockable, hits the user from the front, and was not a FREEZE attack. **4: The counter will always be used and if health - attack damage <= your health will be 1 (rage). * damaged determines whether the entity will receive damage from the hit or not. **0, the damage won't be taken **1, the damage will be taken '''ignoreattackid {int}''' * Animation header. **0, Default, you can't use consecutive attack frames. You need to alternate attack ... with attack 0 **1, You can use all attack frames without limits! '''spawnframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this has no limit. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. '''summonframe {frame}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> {a} </span>{relative}''' * Used to make entity to spawn another entity. Normally it is used to spawn enemy. Spawning with this is limited to 1 entity. * The spawned entity is determined by 'subentity' or 'custentity'. * {frame} determines at which frame the other entity is spawned. *<span style="color: gray;> {x} </span>determines spawn range in x axis. *<span style="color: gray;> {z} </span>determines spawn range in z axis. *<span style="color: gray;> {a} </span>determines spawn range in y axis. * {relative} determines where the other entity is spawned. **0, count from the spawner. Spawned entity will face same direction with the spawner. **1, count from screen offset. * Summoned entity can be killed with 'unsummonframe'. * Regardless of spawned entities, 'group' settings (see below) in level texts won't prevent them from being spawned at all. Though, after they are spawned, 'group' will still count them. * Summonframe also populates a hidden value on the parent entity with the child entity. This does two things - it allows you to later use the Unsummon command to kill the child entity, and also automatically kills the child entity when parent entity dies. That's also why you can only "summon" one entity at a time without script, but you can "spawn" as many as you want. '''unsummonframe {frame}''' * Used to kill summoned entity which was summoned by 'summonframe'. Obviously you need to use 'summonframe' before. * {frame} determines at which frame the other entity is spawned. '''subentity {name} / custentity {name}''' * {name} is the name of spawned entity declared in MODELS.txt. That means the entity must be loaded in MODELS.txt before you can use this. * Or, if you don't want the spawned entity always be loaded, you can use 'load' command in Entity's header data above so when this entity is loaded, the spawned entity will loaded too. * This is used together with 'spawnframe' or 'summonframe'. * {name} determines what/which entity will be spawned or summoned with spawnframe or summonframe. '''weaponframe {frame} {weapon}''' * This is used to switch weapon in an animation. * {frame} determines at which frame the weapon is switched. * {weapon} is weapon's number determines which weapon will be used to replace. * Obviously you need to provide weapon sets for the character first before using this. ==Frame Properties== '''delay {int}''' * {int} is a number that tells how slowly the animation plays. 1 is extremely fast, past 25 will go very slow. * {int} is measured in centiseconds, or hundredths of a second. Pretty fast. * Can be used multiple times in one animation to change speed mid-animation '''offset <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Determines where the "base" of the animation is. * The center of the entity's "shadow" graphic is placed here if the player is on the ground. Also used by enemies to find where you are. * 'offset 0 0' would be the upper left corner. Larger <span style="color: gray;>{x}</span> values move the <span style="color: gray;>{x}</span> down. Larger <span style="color: gray;>{y}</span> values move the <span style="color: gray;>{y}</span> right. * You can use negative numbers or numbers outside of the frame's edges. * Common symptoms of incorrect offsets are misplaced shadows, sudden "warps" to different positions and back, and enemies/shadows who seem to think you're ten feet away. * Can be used multiple times in one animation to change position mid-animation '''bbox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> <span style="color: gray;>{z}</span>''' * Determines where the entity can be hit. * <span style="color: gray;>{x}</span> and <span style="color: gray;>{y}</span> are the x and y coordinates of the top left corner of the box, starting from the top left corner of the frame and moving right/down. <span style="color: gray;>{right}</span> is how far to the right of <span style="color: gray;>{x}</span> the box extends. <span style="color: gray;>{down}</span> is how far down from <span style="color: gray;>{y}</span> the box extends. * <span style="color: gray;>{z}</span> determines how wide the hit area in z axis. It extends to back and front. For instance, setting z to 20 means, the attackbox can hit 20 pixel away to back and front. NOTE: the axis of this z is not same with levels' z axis. * You can use negative numbers or numbers outside of the frame's edges. This can save a bit of memory by shaving a few excess rows or columns of pixels off an animation. * Can be used multiple times in one animation to change hittable areas mid-animation. * To give an entity frames where they cannot be hit, use 'bbox 0 0 0 0 0'. Be sure to add a new bbox when the entity is vulnerable again. * For items, this determines where the object can be picked up from. '''frame {path}''' * {path} points to a graphics file to be used in this animation. * If You don't want any graphics for the frame , You can use frame NONE. * The frame will be displayed at the entity's position. It's about as simple as it sounds. * OpenBoR supports 256-color (or lower) .bmp, .gif, .pcx or .png files. However, .bmp is too big so choose between the latter. .png is recommended. * Image's extension can be omitted (e.g idle instead of idle.gif) * If they were more than one images with same name but different extension and there's no specified extension, OpenBoR will search in this order: .gif, .bmp, .pcx then .png * When the animation is played, OpenBoR will play from the 1st defined frame to the last. It will loop back if 'loop' command is declared (see above) * For 'frame' based commands and scripts, the 1st frame is counted from 0, the 2nd is 1 and so on. * If you want to convert a lot of images which are already in the desired pallette into .gif files, you may want to try Irfanview (at http://www.irfanview.us/). '''alphamask {path}''' * {path} * Default: NA * Path to a grayscale image (usually in PNG format) to be used as the alpha mask for the following frame or layer. * The usage of the alphamask command is exactly the same for both animations and background/foreground layers of levels. The requirements are as follows: * The mask must have exactly the same width and height as its corresponding sprite. * The transparent pixels in the sprite must match exactly with the fully transparent (grayscale value 0) pixels in the mask. Any transparent pixels in one image that aren't transparent in the other will cause undefined behavior - anything from the mask not working to a complete engine crash. * If you're trying to conserve memory, use alpha masks only where they are absolutely necessary. Masked sprites take up twice as much memory as unmasked ones. * Each alpha mask is only applied to the frame immediately following the alphamask command. If you want to use the same mask for multiple consecutive frames, you will have to use the alphamask command before each frame. ''This is different from how most other animation parameter commands work.'' * Alpha masking only works in 16-bit and 32-bit color modes. ''8-bit mode is not supported.'' * '''Alpha masking can't be mixed with other alpha effects from the alpha or drawmethod commands.''' If both are present, the alpha mask will override the other effect. * At the time of this writing, alpha masking doesn't work with drawmethod effects. If present, drawmethod will override the alpha mask. This will be fixed in the future. Animation Example: <pre> alphamask data/chars/mr_iceblock/masks/right-0 frame data/chars/mr_iceblock/right-0</pre> Alpha masks can also be used for background and foreground layers of levels. <pre> alphamask data/bgs/level1layer-mask bglayer data/bgs/level1layer</pre> '''attack{#} <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {power} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' <span style="color: red;>'''There are two ways to set an attack box, since build 4183:'''</span> the ''old'' method, with multiple parameters on the same line (above) and the ''new'' method, where all the parameters were broken in several lines, which makes easier to read. * An attack box which can hit bboxes * OpenBoR supports 10 different attack boxes by default and {#} determines which one the frame is using. There's no space between 'attack' and {#} though. * You can only have one type of attack box per frame (that is, you can't have two attack boxes or an attack and an attack4 box in the same frame). You can 'fake' an extra box or two by adding in extra frames with different boxes and changing the delay accordingly, but this takes up more memory (for the extra frames) and doesn't work perfectly, so try to do so sparingly. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * {damage} determines how much damage the attack does. Setting it to 0 also works. Great for making launchers, slams and paralyze attacks. * {power} is an integer value that determines how strong the knockdown effect of this attack. 0 means no knockdown, 1 means knockdown level 1, etc. This is used in conjunction with 'knockdowncount' (see above). * {block} is a binary value which determines if an attack is unblockable. * {noflash} is a binary value which controls whether the flash is displayed. 0 means flash, 1 means no flash. * {pausetime} is an integer which will cause the attacker and attackee to be paused for {pausetime} if the attack hits something. * <span style="color: gray;>{z}</span> determines attackbox' width in z axis. * If you change or repeat an attack box's declaration later in the animation, you can create combos in same animation. However, a certain amount of time must pass before targets can be hit again (This can be avoided with 'fastattack'). Also, you must have at least one frame with a blank attack box (One set to 'attack 0') between the two frames or sets of frames which combo. * You can use negative numbers or numbers outside of the frame's edges. * Can be used multiple times in one animation to change hit areas mid-animation * When the attacking part of the animation is over, use 'attack 0'. Otherwise, the attack box will remain and can continue hitting people for the rest of the animation! * Each 'attack{#}' has respective PAIN, FALL and DEATH animation. For instance, if attacker hits opponent with attack2, the latter will play PAIN2 (if attack2 doesn't knock him/her down) or FALL2 (if attack2 knocks him/her down) or DEATH2 (if attack2 kills him/her). <span style="color: red;>'''The new method:'''</span> Commands with multiple parameters are being broken down into single line items. This will make text files more readable and easier to debug. It will also help to "future proof" commands and avoid conflicts as we go forward. * attack.block.cost - See guardcost. * attack.block.penetrate - See attack{#} {block}. * attack.counter - See counterattack. * attack.damage.force - The attack's standard damage output. * attack.damage.land.force - damageonlanding {value} * attack.damage.land.mode - damageonlanding {type} * attack.damage.lethal.disable - This attack cannot finish off the target - only reduce it to 1 HP. * attack.damage.recursive.force - See DOT {force}. * attack.damage.recursive.index - See DOT {index}. * attack.damage.recursive.mode - See DOT {mode}. * attack.damage.recursive.rate - See DOT {rate}. * attack.damage.recursive.time - See DOT {time}. * attack.damage.steal - Damage done by this attack will be added to attackers HP. * attack.damage.type - Sets attack type. Same as {#} in attack{#} * attack.effect.block.flash.model - See blockflash. * attack.effect.block.sound.path - Path to sound that will play when this attack is blocked. * attack.effect.hit.flash.disable - See noflash. * attack.effect.hit.flash.model - See hitflash. * attack.effect.hit.flash.sound - See hitfx. * attack.index - Currently no effect. This is for future support of multiple attack boxes. * attack.ground.mode - See otg. * attack.map.index - See forcemap {map}. * attack.map.time - See forcemap {time}. * attack.position.x - See attack{#} <span style="color: gray;>{x}</span>. * attack.position.y - See attack{#} <span style="color: gray;>{y}</span>. * attack.reaction.fall.force - See attack{#} {power}. * attack.reaction.fall.velocity.x - See dropv {speedx}. * attack.reaction.fall.velocity.y - See dropv {speedy}. * attack.reaction.fall.velocity.z - See dropv {speedz}. * attack.reaction.freeze.mode - Freeze target (requires freezetime). Set forcemap = -1 to apply target's fmap. * attack.reaction.freeze.time - Time target remains frozen. * attack.reaction.invincible.time - Time to remain invincible after hit. * attack.reaction.reposition.direction - See forcedirection. * attack.reaction.reposition.distance - See grabin {distance}. * attack.reaction.reposition.mode - See grabin {mode}. * attack.reaction.pain.disable - See noreflect. * attack.reaction.pause.time - See attack{#} {pausetime}. * attack.seal.cost - See seal {energy}. * attack.seal.time- See seal {time}. * attack.size.x - See attack{#} {width}. * attack.size.y - See attack{#} {height}. * attack.size.z.1 - See attack{#} <span style="color: gray;>{z}</span>. * attack.size.z.2 - Depth of bbox toward player. When this is defined, z.1 becomes depth into screen. * attack.staydown.rise.time - See staydown {rise}. * attack.staydown.attack.time - See staydown {riseattack}. * attack.tag - Neutral integer value not utilized by engine in any way. Use this to add your own custom tags or flags to an attack box for scripting. Protip: OpenBOR script supports bitwise logic - you can store a LOT of information in a single integer if you are careful and plan ahead. '''attack11,attack12,...''' * These attacks are only usable if you have increased attacktype limit. To increase the limit use 'maxattacktypes' (see details above in Models.txt section). * After they are available, they work just like other attacks. That also means respective PAIN,FALL and DEATH animations are also available. '''blast <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * '''This command is <span style="color: red;>DEPRECATED</span> and should not be used''' thanks to some strange behaviors which can lead to bugs in things like knockdowncount. A combination of attackbox, dropv and damageonlanding (see Attackbox Supplement below) can replicate this command. * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * blast attacks always knock the enemy down, and sends them flying farther than normal. A 'blast'ed enemy will also be able to hit other entities and knock them down. '''shock <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A shock attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their SPAIN or SHOCK animation. '''burn <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A burn attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this attack hits an enemy or player, they will play their BPAIN or BURN animation. '''freeze <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {time} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * A paralyzing attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * The target will be frozen solid for {time}. They will be unable to attack, move, use specials, etc. If they have an fmap, they will change to that pallete. * {time} is measured in seconds. * Any attacks to a frozen target will cause knockdown. Freeze attacks on their own do not knock enemies down (Unless they were frozen to begin with). '''steal <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span> {damage} {knockdown} {block} {noflash} {pausetime} <span style="color: gray;>{z}</span>''' * An attack box which can hit bboxes. * Unless otherwise specified, this works exactly like an 'attack' command. * If this box hits a player or enemy, it will drain life from the target and give it to the attacker. '''move <span style="color: gray;>{x}</span>''' * Starting with the next frame, the entity will move forward (x) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (x) to move the entity backwards (Or slow their movement if they move automatically, like a jump attack). * Somewhere above 200, this value will allow an entity to run offscreen, out of play, and into oblivion. If you want to get rid of an entity, this should fit the bill, but otherwise you'll have a suicidal entity. If you ARE trying to kill something, use a value like 1000, just in case. '''movea <span style="color: gray;>{a}</span>''' * Starting with the next frame, the entity will move upward (a) pixels with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (a) to move the entity back down towards the ground (Or maybe a pit if they aren't paying attention!). * This command doesn't work if entity has 'antigravity 100' set (see 'antigravity' in Header Data above). '''movez <span style="color: gray;>{z}</span>''' * Starting with the next frame, the entity will move (z) pixels towards the screen with every new frame. * This value must be set to 0 again to stop the entity from moving any further during the animation. * You can use a negative value for (z) to move the entity away from the screen, towards the background. '''seta <span style="color: gray;>{a}</span>''' * Changes the entity's altitude off the ground to <span style="color: gray;>{a}</span>. * The entity will remain at this altitude until changed again with 'seta' or the animation ends. * If the animation ends and the entity is off the ground, they will fall back down while playing their IDLE animation. * Setting a>0, allows entity to fly above holes or simply not fall to holes. '''platform <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt} *OR* platform <span style="color: gray;>{xpos}</span> <span style="color: gray;>{zpos}</span> <span style="color: gray;>{upperleft}</span> <span style="color: gray;>{lowerleft}</span> <span style="color: gray;>{upperright}</span> <span style="color: gray;>{lowerright}</span> <span style="color: gray;>{depth}</span> {alt}''' * Turns an entity into a walkable platform. * There are 2 ways of setting this command but both works. The 1st is the old one while 2nd is new and updated one. If you not sure which one to choose, just use 2nd one. * This is a bit complicated, so listen up! <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> are the x and z positions at which the platform starts . For 1st form, <span style="color: gray;>{xpos}</span> and <span style="color: gray;>{zpos}</span> aren't required and they uses 'offset' (see above) instead. If you're not sure what to set, just use 'offset' value for them. * <span style="color: gray;>{lowerleft}</span>, <span style="color: gray;>{upperleft}</span>, <span style="color: gray;>{lowerright}</span>, and <span style="color: gray;>{upperright}</span> determine the x position of the four corners of the platform. These numbers are how far from the <span style="color: gray;>{xpos}</span> the corners are. * <span style="color: gray;>{depth}</span> is the z depth of the platform: how far it stretches from the <span style="color: gray;>{zpos}</span> to the top of the screen. * {alt} is used to control the height of the platform. It's measured in pixels. So for a platform with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the platform. * This can be changed on a per-frame basis to make platforms move up and down or shift left and right (or both, or neither). * If this entity moves with command or script, any entities on top of it will also move together with it. * You can stack multiple platforms on top of each other. If you do, seta commands will be cumulative (that is, if you have a platform with seta 30 spawn on top of one with seta 50, it will be treated as being 50+30= 80 pixels off the ground, instead of 30 or 50.) '''sound {path}''' * {path} points to a sound effect. The sound will be played as soon as the next frame is reached. * You can declare more than one, in different frames that is. Beware though, the previous played sound will be immediately stopped when new one is played. '''fshadow {int}''' * This is used to set entity's shadow for the current frame. * Possible values are 0 to 6. The possible shadows for use are same with shadows for 'shadow' command (see 'shadow' above). * This consumes more memory so use with care. '''shadowcoords <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span>''' * Adjust offset of entity's shadow for the current frame. Defaults to current frame's offset. * Obviously the entity must use 'shadow' before using this. * This consumes more memory so use with care. '''itembox <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{right}</span> <span style="color: gray;>{down}</span>''' * An item box which can hit bboxes. This can only be used by 'item' entities. * <span style="color: gray;>{x}</span>, <span style="color: gray;>{y}</span>, <span style="color: gray;>{right}</span>, and <span style="color: gray;>{down}</span> work exactly like in a bbox. * If another entity touches this itembox, the item will be picked up by that entity. * The entity who can touch or pick this item is determined by 'candamage'. See 'candamage' above. '''drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}''' * This command defines how current frame will be drawn. There is a more user friendly/shortcut version after the explanation. * {scalex} is integer value, when set to 256, the frame will be drawn in original width, use different values to scale it. Negative value will flip the frame. * {scaley} is integer value, when set to 256, the frame will be drawn in original height, use different values to scale it. Negative value will flip the frame. * {flipx} is integer value, when set to 1, the frame will be flipped leftright. * {flipy} is integer value, when set to 1, the frame will be flipped updown. * {shiftx} is integer value, use to lean the sprite. Might not be quite useful, it is used by gfxshadow, just add it. * {alpha} is integer value. ** 0 = No alpha effect. ** 1-6 = Alpha 1-6 ** -1 = Use entity's alpha. * {remap} is integer value. Will be overriden by {alpha}. ** 0 = No remap. ** 1-n = Like a map command in spawn entry, give the entity a colormap. ** -1 = Use entity's colormap. * {fillcolor} is integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. * {rotate} is integer value to specify rotation angle(clockwise), from 0 to 359. If you use a value out of the range, it will be changed automatically, for example, 370 will be changed to 10, -20 will be changed to 340. * {fliprotate} is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * This command affect all frames starting from current frame. If you want to stop it, use 'nodrawmethod' below. NOTE: Here are the new drawmethod commands, uTunnels changed some of the from the old logic (like using 0~1.0 instead of 0~256 for scale to make it more user friendly) '''drawmethod scale {scalex} {scaley}''' * If scaley is not specified, it is the same as scalex. For example, drawmethod scale 1.5 will scale the whole sprite by 1.5. '''drawmethod scalex {scalex} drawmethod scaley {scalex}''' * These 2 are subset of the previous scale command. '''drawmethod flipx {0/1} drawmethod flipy {0/1}''' * useful to flip the frame in X or Y direction (or horizontal and vertical) '''drawmethod shiftx {value}''' * Others may call that "shear" or "lean", but anyway, it is usually for gfxshadow, it is unlikely you need this. A value of 1.0 is the same as 256 in old drawmethod command. '''drawmethod rotate {angle}''' * Rotate the sprite, clockwise. '''drawmethod fliprotate {0/1}''' * If the rotation is affected by entity direction. '''drawmethod fillcolor {color}''' * Like the old command. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. '''drawmethod remap {int}''' * Leave it alone or use -1 if you want to use current map. Don't use 0, because it means default palette. '''drawmethod alpha {int}''' * Like above, use -1 or leave alone to avoid overriding. '''drawmethod channel {r} {b} {b}''' * When using alpha 6, you can specify opacity for each channel (r, g or b), or leave the other 2 alone to set all the 3 channels. * For example the code below will grand the entity 25% opacity: '''drawmethod alpha 6 drawmethod channel 0.25 drawmethod channelr {r} drawmethod channelg {g} drawmethod channelb {b}''' * These are subset of channel. '''drawmethod tintmode {int} drawmethod tintcolor {color}''' * These 2 will tint the sprite with given tintcolor, in alpha mode tintmode. The color use same format as fillcolor. '''drawmethod clip <span style="color: gray;>{x}</span> <span style="color: gray;>{y}</span> <span style="color: gray;>{w}</span> <span style="color: gray;>{h}</span>''' * This one is on svn but is still experimental. **X - Start point in x axis (horizontal) **Y - Start point in y axis (vertical) **W - Width of the cropped area (horizontal) **H - Height of the cropped area * All values starts at the IMAGE EDGE, not from the image axis, so it will start at the top left position. The easiest way to get those values would be using OpenBORstats or other editor and draw a attackbox/body box where you want. * [[File:Openbor_clip.png ]] * <span style="color: red;>'''Important info:'''</span> Gfxshadow will still show the '''whole sprite''', not only the cropped area. And Mirror won't show the sprite ''at all''. '''nodrawmethod''' * This command disables 'drawmethod'. * Use this with 'drawmethod' of course. See 'drawmethod' above. '''hitfx {path}''' * {path} should point to a .wav file. * If this animation has an attack box which makes contact with a victim, this sound will play instead of the normal 'beat1.wav' sound. * Like the normal hitsfx, the higher the attack power, the slower this sound will play. '''hitflash {name}''' * {name} is the name of an entity declared in MODELS.txt. * If this animation has an attack box which makes contact with a victim, this hitflash will play instead of the normal hitflash for this character. '''idle {flag}''' * Allows current frame to be interrupted by key inputs just like in IDLE animation. ** 0 = Disable key interrupt (default). Also resets previous frame's setting. ** 1 = Enable key interrupt. * For example, if this is set to 1 in ATTACK1 animation, player can cancel the animation by pressing Up and plays WALK instead. * This command works from defined frame to last frame unless resetted. '''@cmd {functionname} {parameter} ...''' * Calls a script function to be run at this frame * Called function can be from generic functions or from animation script * For the latter, make sure the animation script is defined before calling (see animation header above) * Available parameter is relative to the function, some functions have some while some don't have any at all. Check animation script to see how many parameters function has * All parameters (if there are any) must be filled, no more & no less or there will be crash ==Attackbox Supplement== '''grabin {type} {distance}''' * If this command is declared, next nonknockdown attackbox makes entity grab opponent in same manor as normal grab. ** 0 = no effect (used to turn off grabin) ** 1 = Opponent is pulled in while this entity doesn't move ** 2 = Both entity and opponent are pulled each other splitting the distance * {distance} controls how far entity and opponent would be when grabbing starts. * Use this command with non knockdown attackbox of course. '''forcedirection {dir}''' * If this command is declared, opponents hit by attackbox will face specific direction instead of facing entity. ** 0 = no effect (used to turn off forcedirection). ** -2 = Left. It means always left no matter where opponent is hit. ** -1 = opposite of entity. ** 1 = same direction of entity. ** 2 = Right. It means always right no matter where opponent is hit. * Use this command with an attackbox of course. '''damageonlanding {value} {type}''' * If this command is declared, opponents hit by knockdown attackboxes will get {value} extra damage when they land. {type} determines whether attackbox in opponent's FALL is activated or not. ** 0 = attackboxes are not activated. ** 1 = attackboxes are activated. ** 2 = attackboxes are activated and opponents can perform land to safety. * Use this command with knockdown attackbox of course. '''dropv {height} {speedx} {speedz}''' * This command controls opponent's flight path during his/her FALL animation. * {height} controls falling speed in y axis. It works the same with {height} in 'jumpframe'. * {speedx} controls falling speed in x axis. It works the same with {speedx} in 'jumpframe'. Bear in mind, that this setting is relative to this entity's facing direction not opponent's. * {speedz} controls falling speed in z axis. It works the same with {speedz} in 'jumpframe'. * Use this command with knockdown attackbox of course. However it must be declared AFTER that attackbox. * Though, this also works with non knockdown attackbox if it manages to knock down other entity. Usually happens against enemies with 'knockdowncount -1' or at least jumping or falling entities. '''nokill {bool}''' * 0 - (default) The attack will kill the target. Useful to turn NOKILL off. * 1 - The attack won't kill the target but will leave 1 HP. '''stun {int}''' * This command makes the attack freezes opponent for {int} seconds without remap change. * If there's no frozen remap at all, this command is not required cause 'freeze' can make same effect. * Use this command with non knockdown attackbox of course. However it must be declared AFTER that attackbox. '''seal {time} {energy}''' * This command makes the attack disables opponent's freespecials and specials which costs {energy} HP/MP for {time} seconds. IOW the attack silences opponent. * That means if sealed entity can't perform freespecials and special which costs {energy} but can perform ones which costs lesser HP/MP. * Usually used with slams and throws to prevent opponent to break free with special. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''forcemap {map} {time}''' * This command makes the attack changes opponent's remap to {map} for {time} seconds. * Usually used with poison, fire or elemental attacks. Just for graphical effect. * Use this command with attackbox of course. However it must be declared AFTER that attackbox. '''noreflect {bi}''' * This command makes the attackbox only damages target entity without changing target's animation to PAIN or FALL if {bi} set to 1. '''jugglecost {int}''' * This command limits juggling ability of the attackbox. * Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn't matter if the attackbox knocks down or not cause juggling always knock down opponent. * This command is used in conjunction with 'jugglepoints' (see Header Data above). * The command works like this: **If attackbox hits opponent whose 'jugglepoints' is higher than or equal with 'jugglecost', the attack will connect. At this condition, opponent's 'jugglepoints' will be subtracted by that 'jugglecost'. This drops 'jugglepoints' which limits juggling ability. If attackbox hits opponent whose 'jugglepoints' is lower than 'jugglecost', the attack will not connect. At this condition, opponent's 'jugglepoints' will remain the same. '''OTG {bi}''' * This command determines how attackbox affect lying opponent. ** 0 = Attackbox can't hit lying opponent at all ** 1 = Attackbox can hit lying oppoent ** 2 = Attack boxes can only hit down opponents. '''guardcost {int}''' * Defines how much 'guardpoints' will be subtracted from opponent if they block this attack. '''DOT {Index} {Time} {Mode} {Force} {Rate}''' * DOT means Damage Over Time. It works like drain feature but even better. * Drain effect can't kill hit entity but DOT can. Also should DOT effect kill another entity, this entity will get the credit for the kill. * {Index} defines DOT index. Entity may have up to 10 DOT effects at one time. An entity can be hit by more than one DOT effect at once. If entity is hit by same indexed DOT effects, only the latest one will be applied. * {Time} defines how long DOT effect active in centiseconds. * {Mode} defines how DOT effect is applied to hit entity. HP damage is same type as original attack and affected by damage mitigation. ** 1 = Nonlethal HP (can reduce to 1 but not below). ** 2 = MP. ** 3 = MP and nonlethal HP. ** 4 = HP. ** 5 = MP and HP. * {Force} defines amount of damage per tick. * {Rate} defines delay between each tick in centisecond. '''staydown {rise} {riseattack}''' * Gives more or less delay to opponent's rise and riseattack. * {rise} defines how much time in centiseconds to be added or subtracted from opponent's rise time for next rise. * {riseattack} defines how much additional time in centiseconds before opponent's next riseattack. * Both effect are gone once opponent rises or riseattacks. * Use this with knockdown attack of course. If this is used by non knockdown attack, the effect won't show itself until hit entity is knockeddown by other attack. ---- =Using Weapons= *This section provides more info about setting weapons for use in OpenBoR. <span style="color: red;>Warning: Weapons require more memory! A new weapon is a new character, and it has to be loaded into memory at all times! That also means you should load the player with weapon models with load, not know, in MODELS.txt.</span> '''Limitations:''' * Weapons are dropped if you are hit while carrying them by default. You have to use 'weaploss' to change this. * Weapons are lost if you drop them more times than their 'counter' value or go to a new level (even if you don't go to a whole new stage). * Although you can change a player's max health when they pick up a weapon, doing so will not recover thier current life. Entities with a subtype "project" are similar to weapons. Consider both and decide which will work best for you! Weapons require a few changes: '''Original player file:''' * Add this line: weapons {name1} {name2} {name3} {name4} {name5} {original name} * {name#} is the name of the model loaded in MODELS.txt which this character becomes when they pick up weapon #. * {original name} is the name of the character when it doesn't have any weapons equipped. '''Player with weapon model:''' * Create a normal player file with the weapon model's data, but do not include any fields or animations which are the same as the original's. Don't worry if it's normally required, only include altered fields. The original .txt is basically "upgraded" with the new weapon .txt- fields which are different are replaced, new fields get added, and fields which are not mentioned are not changed. * You do need a name, though. And it has to match the name used in the original player's {name#} field. * You also need to redefine freespecials which can still be used. If the animation hasn't changed, you only need to specify the input commands. This way, you can make players lose some freespecials while holding a bulky gun, whip, particle beam, etc. * This entity should have 'type none'. Do NOT give it 'type player', unless you want it to be selectable from the player select menu. '''Item which gives you the weapon:''' * Set it up like a normal item, but give it subtype weapon and weapnum {#} where {#} is the number of the weapon which this item gives players (1-10). Some other weapon-specific commands you may want in the weapon's file: **shootnum {int} **counter {int}**typeshot {bi} If you need more info about them, find them above or use your browser's Find function. ---- =System Files= *This section describes some extra files which is used by OpenBoR. '''flash.txt''' * A standard .txt file for an entity, but the only animation it needs is IDLE. * It should have type none. It doesn't behave any different with any other type, though. * This graphic plays when an attack box of any kind hits a bbox. * The offset is the point at which the flash will be centered. * I would strongly advise NOT setting this to loop, for reasons that will become obvious fairly fast if you do. * BoR doesn't have a default location for this, so it must be loaded in MODELS.txt. * This can be overridden on a per-entity basis with various commands. * Mods can have more flashes. Just make copies of this with different sprite and load them in models.txt. Use 'hitflash' command (see Animation Data above) to use them. '''data/pal.act''' * This is the ingame pallete for mods with 8bit colourdepth. Mods with 16bit or 32bit colourdepth don't need this. See video.txt above for more info. * There are two ways to change or use this file. The first is to use Photoshop, which has built-in support for this format. The second is to use Roel's free online .bmp/.png/.act conversion page. You can find this page at http://www.senileteam.com/boredit/act.php. * If you need the complete original BoR pallette, you can find a copy of the first 128 colors in the lobster boss' alt5.gif frame. Most other frames are missing many colors past 100. '''data/SPRITES/font.gif''' * The most-often used font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font2.gif''' * The font used when a selection is highlighted, and for newly-added scores on the high score screen. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font3.gif''' * This font is used as a 'header' for most options list. It appears at the top of the difficulty selection menu and the options menu, mostly. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font4.gif''' * The large font used for 'game over' and 'next' screens, the timer, and a few other places. * There is a copy of this font in the OpenBoR GUI folder. It's used there as the normal font. * Size of font depends on size of this file. To be exact, it's width/16 x height/16. For instance, if font.gif size is 160x160 pixels, the font size would be 10x10 pixels. Make sure font.gif size is multiplies of 16x16! '''data/SPRITES/font5.gif, font6.gif ...''' * These fonts are extra fonts and are not used anywhere by default. * To make these, simply make font image like other font images above and name it properly. * These extra fonts can be used for rush meter (see 'rush' in levels.txt above) or by script. '''data/SPRITES/shadow{#}.gif''' * {#} is a number from 1 to 6. * This graphic is used as a shadow with negative alpha transparency. * You can make the shadows larger or smaller, but the shadow will not be recentered if you do, so you must change the entity's offsets accordingly. * The shadows are only useful if you're not using 'gfxshadow' (see above). '''data/SPRITES/arrow.gif''' * Normally, an arrow pointing rightward. * When a 'wait' is cleared, this graphic will flash on the right side of the screen for direction right levels (or left side of screen for direction left levels) to tell players to move. It will also be shown if player has the ability to continue moving in the level, but does not do so. * For direction left, this graphic will be flipped. '''data/SPRITES/arrowl.gif''' * This works like the arrow.gif file, but it flashes on the left half in direction left levels. '''data/bgs/hiscore.gif''' * A background for the high score screen. * In order for this to display, 'hiscorebg' must be set to 1 in LEVELS.txt. '''data/scenes/gameover.txt''' * This is a cutscene file. If it exists, it will be played when all players lose all their lives and credits, or if a player chooses to quit during a game. * If this file isn't found, OpenBoR displays the default game over screen: the letters "GAME OVER" displayed in font 4. '''data/bgs/complete.gif''' * This is a .gif file which will be displayed as the background of the stage complete screen. * If this file isn't found, OpenBoR displays the default stage complete screen: "STAGE # COMPLETE" displayed in font4; "Clear Bonus", "Lives Bonus" and "Total Score" with their respective score in font2. * In order for this to display, 'completebg' must be set to 1 in LEVELS.txt. '''data/bgs/select.gif''' * Displays in the background of the player select screen. * select.gif must use the BOR palette. The interesting thing is that, just like the stages backgrounds, that image can use its own palette, by using more than 128 colours. It means that your image can contain up to 256 colours, where the 128 first colours must be the BOR palette, and the 1 to 128 next colours can be custom colours specific to that image. '''data/bgs/unlockbg.gif''' * Displays in the background of the player select screen, once you've completed the game at least once. '''data/bgs/logo.gif''' * This is a .gif file which will be displayed when OpenBoR starts. '''data/scenes/logo.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after logo.gif has been played. * What's this cutscene for if logo.gif already shows logo? Well, the answer is to show more logo or intro animation. You can set music and you can also set disclaimer and author logo here. * If this file isn't found, OpenBoR immediately goes to intro.txt (see below). '''data/scenes/intro.txt''' * This is a cutscene file (see next section for info). If it exists, it will be played after cutscene from logo.txt has been played. * Like the name says, it's used to show intro cutscene. Aside from that, this cutscene will be replayed if there's no action in title screen for couple seconds. * If this file isn't found, OpenBoR immediately goes to title screen and there's no scene to replay. '''data/scenes/howto.txt''' * This is a cutscene file (see next section for info) which has connection with Howtoplay option in main menu. * Like the name says, it's used to show Howtoplay cutscene. If your mod have lots of moves, it's highly recommended to set this. * If this file isn't found, Howtoplay option in main menu will be useless meaning nothing will happen if it is clicked. ---- =Cutscene Files= *This text is for setting animated .gif and music to play in a cutscene in levels.txt. Aside for inbetween levels cutscenes, it is also used for setting intro, gameover and howtoplay scene. It's optional but mod would look better if you set some. '''music {path} {loop}''' * {path} points to a .bor music file which will play. * {loop} determines if the music loops. **0 = no looping. **1 = looping. * Played music will override the previous one. '''animation {path}<span style="color: gray;> {x} </span><span style="color: gray;>{y} </span>{skip} {noskip}''' * {path} points to an animated .gif file which will be played. *<span style="color: gray;> {x} </span>and<span style="color: gray;> <span style="color: gray;>{y} </span></span>are the x and y positions of the top left corner of the .gif. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated gif should be same as mod's resolution (see video.txt above) * It is possible to use smaller gif but there will be black box in unused space when scene is played '''video {path} {skip} {noskip}''' * {path} points to an .webm file which will be played. * {skip} is a flag that allows players to skip current animation. Set to 1 to enable it. * {noskip} is a flag that prohibit skipping. Set to 1 prevent skipping. * The size of animated video should be same as mod's resolution (see video.txt above) * It is possible to use smaller video but there will be black box in unused space when scene is played '''silence {int}''' * If {int} is 1, the current song will stop playing at current scene ---- =Select Screen Files= *This text is for setting custom select screen and allowed players in levels.txt. It's optional. '''music {path} {loop}''' * {path} points to a .bor music file which will be played during this select screen. * {loop} determines if the music loops. ** 0 = no looping. ** 1 = looping. '''background {path}''' * Set backgrounds for select screen. If it's not provided, default select.gif will be used instead. * {path} points to background graphic. * Background graphic must be paletted like select.gif or select.png. The 1st 128 colors must be same with pal.act your mod is using in 8bit colourdepth. * However in truecolor mode, any palette will do '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for current level set. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the mod. If you load saved game, it defaults to old one. '''load {name}''' * This forces engine to load other entity into memory so the entity can be used. * {name} is name of loaded entity. * Normally this is used to 'load' players which aren't loaded yet i.e only declared with 'know' in models.txt so they can be selected in this select screen. * Before using this, the entity must be declared with 'know' in models.txt. ---- =Level Files - Level Design= This text is for setting levels and spawned objects in them. It's not mandatory actually but if there's no level where would players go to? Due to lots of features, this is divided into 2 parts. This part is for level design and the 2nd part is for setting spawned objects. ==Graphics== '''bglayer {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' '''background {path} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {quake} {neon}''' * These 2 command have same effect which is create a background layer with the image at {path}. * The image used must have a width which is a multiple of 4 (ex. 4, 200, 128, not 3, 202, 130). * The height could be any size but make sure it matches screen resolution to avoid void background areas. * Just like any image used by OpenBoR, background and bglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work. * The background is not strictly required, but it controls the global palette. Both the “setpalette” command and the panels’ “neon” configuration are affected by this palette and only work if all layers use the same palette. * By default, background has a xratio of 0.5 * The graphic automatically repeats if the stage is longer than the background. * Layers are drawn in the order they are defined; currently, up to 100 are supported. However ‘background’ sets the bottommost layer while ‘bglayer’ sets layers in front of it. * {xratio} and {zratio} determine how fast the layer will scroll; 1 = same scroll speed as panel, 0.5 = same as background, any float value can be used for them. It works also in levels with direction up or down but the layers will autoscroll just like background. * {xposition} and {zposition} determine where the top left corner of the first layer will be. {xposition} is measured from left for direction right levels, from right for direction left, from bottom for direction up and from top for direction down levels. * {xspacing} and {zspacing} determine how how much blank space there will be between repeated layers. Only works if you set repeating layers (see below). * {xrepeat} and {zrepeat} determine how many times the image will repeat. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * use 1 for {transparency} to have your transparency color not appear. Remember that this is more processor intensive, so don’t use it on images that won’t benefit from it. And don’t use it for ‘background’ too since it’s the bottommost layer. In 16/32 bit mode, pure black color will be used instead. * {alpha} will display the image using alpha transparency. It works just like for entities. Possible values are 0 to 6. Don’t use it for background too. * {watermode} determines water effect. Currently there are 3 modes. ** 0 = No water effect for this bglayer ** 1 = Water effect for this bglayer is on ** 3 = Mode 7 effect * {amplitude} determines the amplitude of sine wave for water effect. Only apply if {watermode} is not 3 (see below) * {wavelength} determines length of sine wave in pixels. It’s repeated since it’s sine wave. Only apply if {watermode} is not 3 (see below) * {wavespeed} determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * When {watermode} is set to 3, the next 3 parameters ( {amplitude} {wavelength} {wavespeed} ) becomes new ones: {beginsize} {endsize} {perspective} * {beginsize} and {endsize} defines size multiplier of upper and lower border respectively. The upper border should be smaller than lower one cause the former is farther * {perspective} defines z depth effect it should have ** 0 = No effect (default) ** 1 = Perspective & tile ** 2 = Perspective & stretch * {bgspeedratio} determines the moving ratio of this bglayer relative to main background. Defaults to 0 (no movement). * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. Note: It must be using the global palette (as in, using same palette as background) for Neon to work. '''bgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in horizontal direction. * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means right-to-left, 1 means left-to-right '''vbgspeed {speed} {dir}''' * Causes the background of the stage to scroll by automatically in vertical direction.(4287+) * {value} should be a number from 0 to 30 or so. 0 means no movement, 1 means slow movement, and anything above that means faster movement. * {dir} controls the direction that the background moves in. 0 means up-to-down, 1 means down-to-up * use vbgspeed+bgspeed combo for diagonal levels '''water {path} {warp}''' * Optional. * {path} points to a graphic file which will be used as a watery background. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * the graphic appears at the {BGHeight}, which is defined with 'z' in LEVELS.txt. If no {BGHeight} is set, it will appear right under background. * If you use 'rock 0' or do not include the rock command, the water will be warped by a sine wave (It will slither back and forth). {warp} will determine how quickly the waving will occour. * If you use 'rock 1' in the same stage, the water will float past in parralax (The graphic gets larger as it approaches the playing area). {warp} will determine the speed. '''rock {int}''' * Optional. ** 0 means nothing. ** 1 means the level floats up and down slightly. ** 2 will cause the stage to remain steady for a second or so, then quickly shake twice. Should resemble the steady rocking on a train ride. ** 3 will cause the stage to shake with a constant, steady rumbling, with occasional 'hiccups'. This one looks like what you might feel if you were riding in a moving van or on top of a moving eighteen wheeler. '''mirror {bi}''' * Optional. * Determines whether or not there is a mirror in the background. ** 0 means no mirror effect. ** 1 means that sprites will have a "mirror" image drawn between the background and panels. '''panel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel. {neon} and {scrn} are optional fields. If you aren't using them, put the word 'none' in their place. * Just like any image used by OpenBoR, panels must use paletted images. In 8 bit colourdepth (default), it must use same palette as 'background' (see above). In 16/32 bit, it can use different palette * Beware though, if panels use different palette than background, 'palette' command (see below) won't work * Panels are mostly used as the floor and walls of a screen. However, in pseudo travel levels where background are autoscrolling (see bgspeed below), sometimes panels aren't used at all and replaced by blank image * If a panel is declared in autoscrolling level, it won't autoscroll. Great for platforms or vehicles! * In default resolution, panels are normally 244 pixels high (which is 240 pixels from screen height + 4 extra pixels for quake effect) but should be 256 if the stage is set to rock up and down. It may also need to be extended depending on the 'z' values set in LEVELS.txt * In alternate screen resolution (see video.txt above), panels are at least same with screen height + extra pixels for quake effect. For instance, in 640x480 resolution, panels height is 488 * You can use whatever width you want, but it's a good idea to use simple values like 100, 150, or 360. It makes it much easier to add up the total length of the stage. * All panels in a stage should have the same length and height. * If you overlap part of the image used in one panel with another, the computer will still try to draw both. Be nice to computers. Don't overlap panel layers. * Normal mode panel layers are just plain images. They have no visual effects. * Neon mode panel layers use 'pallete cycling': certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. * Screen mode panel layers have alpha transparency. That means, they blend with the colors behind them, darker colors are more transparent, and brighter colors will blend less. * You can have up to 26 panels in a stage. They are labelled by OpenBoR from a to z. This is how OpenBoR thinks of them, don't actually put those letters in the panel declaration. '''frontpanel {norm} {neon} {scrn}''' * {norm}, {neon}, and {scrn} are paths which point to the normal, neon, and screen graphics for a panel layer which will be displayed on top of all other sprites and graphics except for the HUD. This can be used to make foregrounds. * {neon} and {scrn} are optional fields. If you aren’t using “neon” but wants to use “screen”, put the word ‘none’ on it’s place. * If you aren’t using any other rather than normal, you don’t need to put anything after the path. * Just like any image used by OpenBoR, frontpanels must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if frontpanels use different palette than background, ‘palette’ command (see below) won’t work * frontpanels display in the order they are declared and repeat when they run out. You don’t need to declare an order like with normal panels. * frontpanel has its own scroll speed ratio (xratio) of 1.5 which can’t be changed. If you don’t like it, use ‘fglayer’ below instead '''order {panel#}{panel#}{panel#}...''' * Determines the order of panels in a stage. * {panel#} is a letter a through z which corresponds to a panel. There should not be spaces between the panel declarations (ex. order abcabcada, not order a b c a b c a d a). * The same panel can be used more than once. * You can have up to 1000 panels ordered, but there's a catch: the engine can't read a line with 1000 characters in it (The max is somewhere around 100). To get around this, you can place the additional panels on another line with a separate order declaration, like this: order abcdefghij order klabcd order eeabcdef * That '...' at the end doesn't mean you should put a ... at the end. It means the pattern repeats like it has been repeating so far. * If you use 'direction left', panels will be displayed from left to right, starting with the last order and working up. In other words, the previous declaration would become 'eeabcdefijklabcdabcdefgh' instead of 'abcdefghijklabcdeeabcdef'. '''loadingbg {path} {set} {bx} {by} {bsize} {tx} {ty} {tf}''' * This command allows custom loading background to be displayed while the current level are being loaded. * {path} determines the location of used background. * {set} determines how loading screen would be. **-1 = default black screen with loading and status bar. **0 = no loading screen. **1 = loading screen background and status bar. * {bx} and {by} determines x and y coordinates of loading bar top left's location respectively. * {bsize} determines loading bar's length. * {tx} and {ty} determines x and y coordinates of "LOADING" text location respectively. '''palette {path} {a1} {a2} {a3} {a4} {a5} {a6}''' * This command loads new palette to be used by script or by 'setpalette' command (see below). However it only works if panels, frontpanels, bglayers and fglayers use same palette as background * {path} is the path to loaded palette in .act format. For instance: data/bgs/staage1/pal001.act}. * {a1}, {a2}, {a3}, {a4}, {a5} and {a6} are flags that determines usage of respective transparency. a1 means alpha 1 transparency, a2 means alpha 2 and so on. * This transparency feature costs 384kb memory when palette is loaded so use with care. * This command can be declared more than once if more palettes are required. '''cameratype {bi}''' * This sets camera's movement relative to player's movement. Camera means screen which shows level we are playing. It is much easier to understand if level allows scrolling back since you can see how camera moves if player goes back. ** 0 = Camera only follows player's horizontal movement. ** 1 = Camera follows player's horizontal and vertical movement. Normally used in wide levels and vertical levels (for 2D mods) * If set to 1, panel's height controls how far up or down camera can go (both in z and y). '''fglayer {path} {z} {xratio} {zratio} {xposition} {zposition} {xspacing} {zspacing} {xrepeat} {zrepeat} {transparency} {alpha} {watermode} {amplitude} {wavelength} {wavespeed} {bgspeedratio} {quake} {neon}''' * This is for setting custom foreground layer in current level. * {path} is the location relative to data folder where the graphic is * Just like any image used by OpenBoR, fglayers must use paletted images. In 8 bit colourdepth (default), it must use same palette as ‘background’ (see above). In 16/32 bit, it can use different palette * Beware though, if bglayers use different palette than background, ‘palette’ command (see below) won’t work * {z} sets location of the layer. Give positive value to make it closer to screen or negative value to make it farther from screen. * Other parameters ( {xratio}, {zratio}, {xposition}, {zposition}, {xspacing}, {zspacing}, {xrepeat}, {zrepeat}, {transparency}, {alpha} and {bgspeedratio} ) have same effect like in ‘bglayer’ above. * {quake} is a boolean setting. 0 (default) will make the layer to not shake when the screen a quake happens. 1 will make it to shake. * {neon}, unlike panel, IS NOT the path to the file we will use as neon, it is a boolean value: ** 0 disabled (default) ** 1 enabled * Neon uses ‘pallete cycling’: certain colors slowy change to different colors. To be more specific, colors 128 through 135 in the pallete will be cycled by two steps three times each second. '''Note: It must be using the global palette (as in, using same palette as background) for Neon to work.''' * {watermode}, {amplitude}, {wavelength} and {wavespeed} also works for bglayer and background (but not for frontpanel) – 6391+ '''cameraoffset<span style="color: gray;> {x} </span>{z/y}''' * This command is used to control point the camera focuses on. * Camera means view of game. You won't see any effect of this unless your levels are wide. * Positive value for<span style="color: gray;> {x} </span>shifts camera right, for {z/y} shifts camera down. * Negative value for<span style="color: gray;> {x} </span>shifts camera left, for {z/y} shifts camera up. '''scrollspeed {int}''' * This command defines how fast screen scroll when player scroll the screen * Default value is 1 which means screen scrolls 1 pixel per frame * Recommended in high resolution mods ==Non-Graphics== '''type {type} {nospecial} {nohurt}''' * Optional. * {type} is a binary value which determines if the stage is a normal stage (0) or a bonus stage (1). * Bonus stages end when all obstacles are destroyed, when there are no more items or when time runs out. Players won't lose a life if time runs out. **0 = normal level **1 = Used for bonus levels so a life isn't taken away if time expires.level->type == 1 means bonus level, else regular **2 = custom HUD (no bgicon.gif) * {nospecial} Can use specials during bonus levels (default 0 - yes) * {nohurt} Can hurt other players during bonus levels (default 0 - yes) '''music {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played during the stage. * {offset} is position in bytes music will return to when it loops. For instance, with a .bor file with 128000 byte size, setting offset to 64000 would make music loop from halfway of the music. * you can change the music during a stage using "at" and giving a new file path, like this: <pre>music data/music/newmusic.ogg at 600</pre> '''bossmusic {path} {offset}''' * Optional. * {path} points to a .bor music file which will be played when a boss appears. Boss is enemy who has 'boss 1' set when he/she appears. * {offset} works same way as in 'music' above. '''spawn1<span style="color: gray;> {x} </span>{z} {a}''' * Optional. *<span style="color: gray;> {x} </span>is relative to the starting edge of the screen.<span style="color: gray;> {z} </span>is relative to the stage's minimum z value.<span style="color: gray;> {a} </span>is relative to the ground. *<span style="color: gray;> {x} </span>is measured from left for levels with direction right and both and it's measured from right for levels with direction left. * Although<span style="color: gray;> {x} </span>could be any value, its maximum value is 320. Value more than 320 will be deducted by 320. For instance, setting x = 540 will put player in x = 220 instead (220 = 540 - 320). * However, it's possible to give<span style="color: gray;> {x} </span>negative value in direction both and right or big value in direction left and leftright to put player1 offscreen when level start. Why would you want this though? *<span style="color: gray;> {z} </span>could be any value but it can't put player 1 beyond maximum z value. * Setting<span style="color: gray;> {a} </span>> 0 makes player falls down on respawn. Default value for a is 300. NOTE:<span style="color: gray;> {a} </span>only effect respawn not when level starts. * If there's a hole on player's spawn spot, the spawn spot will be shifted up or down to safe place temporary. '''spawn2<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 2. '''spawn3<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 3. '''spawn4<span style="color: gray;> {x} </span>{z} {a}''' * Optional. * Works exactly like spawn1, except that it sets the respawn position for Player 4. '''allowselect {playername1} {playername2} ....''' * Defines allowed players in this select screen just for this level. * {playername#} is the name of player. You can define more than one but no need to repeat same one. * Make sure the allowed players are loaded otherwise they won't be available. OTOH if a player is loaded on a level, he/she is affected by this settings too. * The allowance or disallowance only works when playing the level. If you are using a player which is not allowed in this level (either because you selected him/her in previous select screen or that player is allowed in previous level), you can still use that player. Beware though, once you continue, you can't choose him/her again! At least in this level. '''direction {dir}''' * Determines which direction the screen scrolls in. * {dir} can be right, left, both/rightleft, up, down, in, out, inout, outin, or leftright. Defaults to right if not declared. **up and down scroll background up and down respectively and automatically. You cannot scroll left or right in these stages. You must use groups to control enemy spawning. Wait doesn't work well here so that means you have to watch the time here. Put time item or simply set time to 0. Panels, neons and screens are not scrolled. **left and right must be scrolled manually, like normal. **both or rightleft is pretty neat. It's like direction right but it allows you to freely scroll left or right. When you reach a wait, you won't be able to move back past the previous wait until all spawned enemies prior to wait are killed. **leftright is similar direction both but it's like direction left instead. **in and out is new scrolling system in which player scrolls in or out respectively. In means up in z axis while out means down. Just like left and right, it must be scrolled manually. **inout and outin is similar to direction both but they are like direction in and out respectively. * Screen, neon, water, etc don't work well in direction in, out, inout and outin. '''settime {int}''' * This stage's time limit will be {int}. * If {int} is 0, the player will have unlimited time. * The timer resets every time a 'wait' group of enemies is cleared. Note that it doesn't reset in between groups, only waits! * Using 'settime 1' isn't funny. Okay, it's a little funny the first time. * Don't forget to use 'Time' items when needed! '''nofadeout {bi}''' * Controls fade out effect for a level ** 0 = (default) Screens fades out when you finish the stage ** 1 = No fade out when the stage finishes '''notime {bi}''' * Determines whether or not the player can see the game timer. '''noreset {int}''' * Determines when clock resets aside from clearing wait, clearing level and time out. ** 0 = (default) Clock resets when another player joins mid-stage and when player respawns. ** 1 = Clock only resets on time out. ** 2 = Clock resets when player respawns. '''noslow {bi}''' * Determines whether or not the game slows down after beating a boss. '''hole {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * A 4-sided invisible hole will be created at the specified point. OpenBoR won't draw a hole or anything there. If you want hole to be visible, use panels or entity. * In Beats of Rage, a hole with default size and special sprite is used. That sprite is hole.gif located in sprites folder. If you want to change the size and visual, you need to set this command AND replace that hole.gif with blank gif. * This is a bit complicated, so listen up! {xpos} and {zpos} are the x and z positions at which the hole is spawned (how far from the start of the stage, and how far from the top of the screen, respectively). * {lowerleft}, {upperleft}, {lowerright}, and {upperright} determine the x position of the four corners of the hole. These numbers are how far from the {xpos} the corners are, not how far from the start of the stage. * {depth} is the z depth of the hole: how far it stretches from the {zpos} to the top of the screen. * {alt} is used to control the height of the hole. (4287+) * {type} the type is a param useful for decide what type of terrain is that hole. * As an example, if you wanted to create a 10x40 parrallelagram ( /_/ ) hole at the bottom of the screen (256) at scroll position 500, you might put **hole 500 256 0 10 10 20 40 * If you create a hole which is not at the bottom of the screen, entities will be visible as they fall off the stage. Probably bad. So place an entity with type none right below the bottom of the hole which resembles the floor. This will cover up almost any entities which fall in the hole. * If used in a stage which scrolls left, the holes will start at the left edge of the starting screen and move right from there. So only holes which would appear in the first 320 or so pixels of the screen will actually be visible, and they'll be at the start of the stage. * The default values are 240, 12, 1, 200, 287, and 45, respectively. * {alt} {type} are optional '''wall {xpos} {zpos} {upperleft} {lowerleft} {upperright} {lowerright} {depth} {alt} {type}''' * Creates a 4-sided invisible wall or platform at the specified point. OpenBoR won't draw a wall or anything there. If you want wall to be visible, use panels or entity. * All of the field except {alt} are the same as they are in holes. * {alt} is used to control the height of the platform. It's measured in pixels. So for a wall with 10 for it's {alt} value would be 10 pixels high, any entity on the platform would be displayed 10 pixels off the ground, and entities would need to jump at least 10 pixels off the ground to get on top of the wall. * {type} the type is a param useful for decide what type of terrain is that wall. Example I want to make a wall splat JUST on walls of type 1 and not type 0. (4287+) * If you want to make a wall which can't be jumped on, simply give it a {alt} value somewhere in the lower thousands. Very, very, VERY few entities should be able to jump on it. * In order for enemies to get on platforms higher than their current position, they need a JUMP animation with a range set for it, and/or an animation which lifts them off the ground. * {type} is optional If you need a graphical exemple, take a look at this example by Maxman. When using wall in the stage, it should be on the z planes, not outside of it. [[File:Wall tutorial2.png]] '''basemap {xpos} {zpos} {xsize} {zsize} {amin} {amax}''' * Creates a 4-sided invisible ramp at the specified point. OpenBoR won't draw a ramp or anything there. If you want ramp to be visible, use panels or entity. (4287+) * {xpos} {zpos} works like wall or holes * {xsize} defines the ramp width * {zsize} defines the ramp size (or wide) in z axis * {amin} defines the lowest height while {amax} defines the highest height [[File:Basemap.jpg]] '''endhole {bi}''' * Optional. * Determines if the rightmost edge of the stage is a pit. * 1 means yes. 0 means no. * Don't use this if your stage scrolls left. Trust me on this one. * This command is outdated and only left for backward compatibility sake. Use 'hole' above instead '''blocked {bi}''' * Optional. * Determines if the edge of the stage is a solid wall. 1 means yes. 0 means no. * Entities who hit the wall will stop moving. * This always appears on the right side of the screen, and if you choose 'scroll left' players will start inside the wall. They warp out when the player moves, but it still looks funny. * If you combine 'endhole' and 'blocked', you'll end up with a blocked exit with a pit behind it. You can only reach the pit by starting behind it with 'direction left' (Which is a very bad idea). * This command is outdated and only left for backward compatibility sake. Use 'wall' above instead '''gravity {value}''' * This sets gravity or falling speed in the level. * It should use negative value. Defaults to -10 * Setting -5 makes characters fall like in water. '''maxfallspeed {value}''' * This sets maximum falling speed in the level. * It should use negative value. Defaults to -60 (6 pixels per centisecond) * Setting -20 (2 pixels per centisecond) makes characters fall like in water. * If you want your character to fall faster, set it to -200 (20 pixels per centisecond). '''maxtossspeed {value}''' * This sets maximum jumpheight in the level. * It should use positive value. Defaults to 1000 '''stagenumber {int}''' * Sets this level's stage number. Stage is calculated per 'next' executed in levels.txt (see levels.txt above). * Normally OpenBoR increments stage number automatically after 'next' is executed or bonus score tallying. However, when the mod has branches, stage number becomes inconsistent to real progress, meaning it only counts how many 'next' instead of how many 'next' which actually has been executed. With this command, stage number will be more consistent. '''noscreenshot {bi}''' * If this is set to 1, players can't make screenshot in current level. Screenshot key itself is still working though. * Players can still access options menu while pausing by screenshot button with this command set 1. '''nopause {bi}''' * If this is set to 1, players can't pause current level. Start key itself is still working and capturable by keyscripts though '''setweap {int}''' * Sets starting weapon in this level for players based on weapon's number. * Weapon number is based on 'weapnum' in weapon's text (see Entity Files: Header Data above). * Make sure the weapon is available before setting this. '''levelscript {path}''' * This command defines which script is run when this level is played * It won't be played again until the level is restarted ---- =Level Files - Level Objects= *Just to reiterate, this part is 2nd part of level files section. This part is setting spawn objects in the level. ==Spawn Properties== '''spawn {name} {bi}''' * {name} is the name of an entity defined in a .txt file which was loaded in MODELS.txt. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * {name} will be spawned (created) in current level. Where and with what attributes are determined by the next set of fields. '''2pspawn''' * If this is declared, the entity is only spawned if there are 2 players playing. '''3pspawn''' * If this is declared, the entity is only spawned if there are 3 players playing. '''4pspawn''' * If this is declared, the entity is only spawned if there are 4 players playing. '''alias {name}''' * The spawned entity will appear to have the name {name} in-game. For instance, if you used **spawn Rugal **alias Hotdog_Man *then when you reached Rugal in the stage, his name would be displayed as 'Hotdog Man'. * The rules from an entity's .txt file concerning names apply here, too. So use '_' instead of spaces if you want to use spaces. '''map {pal}''' * {pal} is a number from 0 to 14 which corresponds to an entity's 'remap' pallete. The entity will use that pallete. '''health {int}''' * {int} is a health value which will be used instead of the entity's normal health. '''2phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 2 players playing. '''3phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 3 players playing. '''4phealth {int}''' * {int} is a health value which will be used instead of the entity's normal health, but only if there are 4 players playing. '''mp {int}''' * For items spawned in a stage. * When a player picks this item up, they'll regain {int} MP instead of it's normal value. '''dying {remap} {health1} {health2}''' * If this entity's health drops to or below {health1}, they will flash between their normal pallete and the {remap} pallete. * If their health drops to or below {health2}, they flash even faster. '''item {name} {bi}''' * Optional. * When this entity dies, a {name} will instantly be spawned in it's place. If entity was in mid-air before dying, {name} will start falling from that entity's last altitude. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * You can't make an entity drop multiple items. '''itemhealth {int}''' * Optional. * Changes the health of a dropped entity to {int} '''itemmap {int}''' * Optional. * Changes the pallete of a dropped entity to {int} '''itemalias {name}''' * Optional. * Changes the name of a dropped entity to {name} '''2pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 2 people playing. '''3pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 3 people playing. '''4pitem {name} {bi}''' * Optional. * Works just like 'item', except that this will only be spawned if there are 4 people playing. '''boss {bi}''' * Optional. * If set to 0, nothing. If set to 1, the character is a boss. When a boss appears, the music will change to the boss music (if it was defined). Killing all the boss characters in a level will kill all other enemies and also end the stage automatically (even if there are still unspawned entities) '''flip {bi}''' * Optional. * If set to 0, nada. If set to 1, the entity will face the opposite direction. Used for obstacles and traps most of the time, but it can also be used to make enemies who spawn on the left side of the screen face towards players from the start. * Can also be used for entities with subtype arrow to make them fly from left to right. '''coords<span style="color: gray;> {x} </span>{z} {a}''' * Determines the x, z, and a positions on the screen where the entity will spawn. *<span style="color: gray;> {x} </span>is relative to the screen's current position, NOT the actual position in terms of the level itself. *<span style="color: gray;> {z} </span>is the position on the Z axis, which is counted from the top of the screen. NOT related to the screen's current position. *<span style="color: gray;> {a} </span>is how high off the ground the entity will spawn. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an enemy, it will magically fall out of the sky. Unless it has a SPAWN animation, in which case it'll play that. * If<span style="color: gray;> {x} </span>is between 0 and 320, and the entity is an obstacle or item, it will magically appear out of thin air. Unless it has a SPAWN animation, in which case it'll play that. * In case you're wondering, the BoR playing field is, in bbox format, 0 320 160 230. Unless, of course, you've changed the {min} and {max} values in LEVELS.txt with 'z'. You can also place enemies outside those ranges, but they'll try to return to the playing field if you do. * Most projectiles will automatically die if their offset is more than 80 pixels offscreen left or right (their x value must stay between -80 and 400). Knives are the only exception: they can go up to 180 either way (-180 to 500). Other entities will also die if they move too far, but they have more leeway (Around 1000 in either direction). Keep that in mind while spawning characters. * Bikers should normally be spawned further out than other enemies. By default, they are spawned either at -200 or (video horizontal resolution +200, in other words, your screen resolution + 200 pixels). '''aggression {value}''' * For enemy spawns. * Spawned enemy's aggression will use this {value} instead of the enemy's normal aggression. '''min_noatk_chance {float}''' * Determines the minimal chance of an enemy attack. '''max_noatk_chance {float}''' * Determines the max chance of an enemy attack. * if you want the enemies to attack every time they have a chance, you can do it like this: <pre>min_noatk_chance 0 max_noatk_chance 0</pre> '''noatk_duration {float}''' * noatk_duration affects how long the no attack period should last in seconds. * Usually you don't need to change that (0.5-0.75 should be fine). '''weapon {name} {bi}''' Give this spawned enemy {name} as a weapon to start with. The enemy will wield this weapon and attack with it. * If enemy is knocked down or dies, the weapon will be dropped. * {bi} determines if model stays in memory or not after current level ends. ** 0 = Model stays in memory. ** 1 = Model is unloaded when current level ends. * Make sure the weapon is available before setting this. '''spawnscript {path}''' * This command defines which script to be run right after entity is spawned * Can be declared multiple times * In multiple spawnscripts case, script will be run from the 1st to the last '''at {pos}''' * For an entity to be spawned, the player must have scrolled to {pos} in the level. * {pos} is scroll position in pixels measured from start of level. For direction both and right, it's measured from left edge. For direction left, it's from right edge. * This must be declared together with other level objects. Normally typed after the latter. ==Other level objects== '''blockade {pos}''' * Optional. Used in direction both levels. * {pos} is scroll position and it's similar to the one for 'at'. {pos} for 'blockade' and 'at' can be different though. * This is to stop players scrolling backwards in levels with direction both at {pos}. If the level is long, you may want to use this since it could be weird being able to scroll back to beginning of level. * It must be followed by 'at'. '''group {min} {max}''' * Also not an entity spawn, also should be followed by 'at'. * Causes entities to be spawned in groups. When the number of enemies goes below {min} (not equal to, below), entities will be spawned until there are {max} enemies onscreen or there aren't any more enemies to spawn in the group. * Group size declarations remain in effect until changed. So use a large group size like 'group 100 100' to "cancel" the grouping. * 'wait' is also counted to 'group' so it's best to put 'wait' first to prevent it being limited by 'group'. * This only prevent enemies and other entities spawned with 'spawn' command above. Entities spawned with 'spawnframe' and 'summonframe' (see above) won't be prevented even if max value has been reached. '''light<span style="color: gray;> {x} </span>{z}''' * This command changes light direction to<span style="color: gray;> {x} </span>{z} for gfxshadow's at defined scrollpos. This is used together with 'gfxshadow' (see above). * If<span style="color: gray;> {x} </span>is not 0, the shadow will lean left or right (256 means 45 degree, try use some values and see what is the best value) *<span style="color: gray;> {z} </span>can't be 0, because it is for the length of the shadow in z direction, 256 will make the shadow as long as its owner's sprite, and 128 will be half length. If it is negative value, the shadow will be flipped head-to-foot. * Must be followed by 'at'. '''load {name} {bi}''' * Used to load a model whose name is {name} in current level. * {bi} determines if model stays in memory or not after current level ends. **0 = Nothing. The model is left alone (IOW, remains loaded) and loop moves on. This is the default action. **1 = Unload model only. The model is unloaded, but the sprites are not. Pretty pointless unless the model has a lot of script attached to it. **2 = Unload sprites only. The mode remains loaded, but its sprites are removed from memory. **3 = You'll notice there there is no third option, but because bitwise logic is in play, 3 effectively means "1 and 2" - model and sprites are unloaded. * This command is for loading weapons models or other entities which shouldn't be loaded until this command is executed. It's useful for memory usage control. * Don't forget to load {name} with 'know' in models.txt! * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''music {path} {offset}''' * Changes current music with this one at specified scrollpos. The change will occur instantly. * If you want previous music to be faded out before playing this one, declare 'musicfade' BEFORE this command (see below). * It works exactly like 'music' above (see Level Designs above). '''musicfade {float}''' * When music changes, this command determines fading out speed of previous music. * Higher value makes fading out faster while lower value makes fading out slower. * Used together with 'at' and 'music' command right above. Declare it BEFORE 'music'. '''scrollx {min} {max}''' * Scrollx defines how far to the left and right player can scroll (allows you to precisely set the X scrolling limit within your panel area). To be detailed, parameters defines min scrollpos and max scrollpos. For instance, scrollx 50 600 will allow player to scroll left to scrollpos 50 and scroll right to scrollpos 600. It's easier to understand with direction both set. * Maximum X scroll area of a level is still limited by panels. You can set scrollX to whatever value you like, '''but OpenBOR will not allow you to scroll beyond the panel area.''' * It must be followed by 'at'. '''scrollz {min} {max}''' * ScrollZ enables vertical scrolling in response to player movement along the Y or Z axis, and controls how far. There's potential to make 3D scrolling stages, but the main use of this is to enable vertical scrolling when players jump. Unlike ScrollX, '''ScrollZ does allow you to go scroll beyond the panel area''', so if you don't set up panels and layers to accommodate you can scroll yourself right out the visual design of a level. Also note that entities are still confined to the level's Z boundaries. That's a good thing, since it means you could set up large ScrollZ values for vertically oriented scrolling but still keep Z movement limited within a defined area. * Obviously {min} is the minimum limit and {max} is the maximum limit. * This command only works in levels with direction left/right/both/leftright or rightleft. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. * It must be followed by 'at'. '''setpalette {palette}''' * Change palette in use to other palette which is loaded by 'palette' (see above). * {palette} correspond to the loaded palette number so if you want to use 2nd palette, set this to 2. * Setting this to 0 or -1, reveerts palette to default palette. * Like other level objects, this command must be followed by 'at' (see above) and also counted by 'group'. '''shadowcolor {R_G_B}''' * This command changes gfxshadow's fill color to {R_G_B} at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to current level palette's index. * Setting {R_G_B} to -1 turns gfxshadow off. * Setting {R_G_B} to -2 turns off fill color gfxshadow. * Example of {R_G_B} format is: 0_0_255 for blue color. * Must be followed by 'at'. '''shadowalpha {index}''' * This command changes gfxshadow's from black shadow to mirrored image at defined scrollpos. This is used together with 'gfxshadow' (see above). * In case you don't understand, this is used to mirror image of entities appear on 'ground'. Useful if the 'ground' is actually water or mirror. Disable normal 'black shadow' 1st with 'shadowcolor' above before using this. * {index} refers to any alpha blending type i.e 1-6. * Setting {index} to -1 turns gfxshadow alpha off. * Must be followed by 'at'. '''shadowopacity {index}''' * This command changes gfxshadow's opacity to to {index} value at defined scrollpos. This is used together with 'gfxshadow' (see above). * {index} refers to opacity value i.e 0-255. * Setting {index} to -1 turns gfxshadow to 0. * Setting {index} to -2 turns gfxshadow alpha off. * Must be followed by 'at'. '''wait''' * This isn't part of an entity's spawn. It doesn't take any arguments either. It should be followed by an 'at', though. * Screen scrolling will be stopped at {pos} in the 'at' command following the wait until all current enemies are killed. * In direction up and down, background scrolling can be stopped also with 'wait' but there's no way to make it auto scroll again. ---- =Music Files= '''Recomendations:''' * Music files tend to be the largest portion of BoR mods, frequently larger than the rest of the mod combined. Some good ways to cut file size are to delete unneeded segments of the song, like silence at the start or end of the file or identical loops in video game tunes. * Chose some decent songs. If you've got different tastes in music, that's one thing, but just choosing random noise is something else. Make sure the music fits. '''How to Convert:''' * You'll need a program called WAV2BOR.exe and music in .wav format. * The wav specs are 16bit PCM, Stereo or Mono and 22KHz sampling rate. * NOTE: The old wav2bor.exe only support Mono. If you want stereo support, get new wav2bor.exe from here <http://lavalit.com:8080/index.php?action=tpmod;dl=item225>. * Also, stereo is only supported in OpenBoR v3.0 and up. * Once you've got the files, place them all in a folder called W2B in your C: drive. This step wasn't neccessary, but if you're having trouble it might fix some problems. * Create a new .txt file, and give it a name with the .bat extension. Add the following line for each .wav you want to convert, then double click on your .bat file to start the batch conversion of your .wav files to .bor music files: /wav2bor.exe {wav} {bor} {artist} {title}/ * {wav} is the name of the .wav file to be converted (make sure it has .wav on the end). {bor} is the file that will end up holding the .bor music. {artist} and {title} are optional fields which can be used for an artist name and song title. Or a dog's name and your favorite food. It doesn't really matter. If you do use them, remember that you must use underscores (_) instead of spaces ( ). ---- =Sound Files= '''data/sounds/beat1.wav''' * Played when an attack hits an entity's bbox. * Normally, this sound will be played slower depending on how much damage the attack deals. If this is a problem, you can disable this with the 'noslowfx' command. '''data/sounds/fall.wav''' * Played when an entity hits the floor after being knocked down. '''data/sounds/get.wav''' * Played when a player picks up an item. '''data/sounds/money.wav''' * Played when a player grabs a score item. '''data/sounds/jump.wav''' * Played when someone jumps. '''data/sounds/indirect.wav''' * Played when an entity hits other entities while being thrown or blasted. '''data/sounds/punch.wav''' * Played when a player uses an attack in their attack chain (Pressing attack from a standing position). Normally only heard if the attack misses. '''data/sounds/1up.wav''' * Played when the player gets a 1-up. '''data/sounds/go.wav''' * Plays three times in a row when the player has beaten all enemies at a wait and can now move forward again. '''data/sounds/timeover.wav''' * Played if the timer hits zero. Also played if all credits are lost. '''data/sounds/beep.wav''' * Played in menus (not in game) when you move up or down. '''data/sounds/beep2.wav''' * Played in menus (not in game) when you select an option. '''data/sounds/bike.wav''' * Required if you have bikers. Plays for bikers, of course. '''data/sounds/block.wav''' * Optional. Plays when an entity blocks an attack. '''data/sounds/pause.wav''' * Optional (build 4183+). Played when pausing. If the file does not exist beep2.wav will play instead. ''Warning: keep an eye on the file size of your .WAVs.'' ---- =Translations= Since version 3959, it is possible to translate the texts used in the engine. The translation file is called "translation.txt" and should be placed inside the "data" folder. Check the file to further instructions. ---- =Script= ==Engine defined functions (Native functions)== '''projectile {relative} {name}<span style="color: gray;> {x} </span>{z}<span style="color: gray;> <span style="color: gray;>{y} </span></span>{direction} {ptype} {type} {map}''' * Despite the name, it can be used to spawn any type of entity. Useful for using more than one "spawnframe" or any other method as it offers much more control. * {relative} - Affects all other settings. See bellow * {name} - name of the spawned position, from models.txt * <span style="color: gray;> {x} </span>- X spawn position, defaults to 0. Accept decimals. If relative is 0, the position will count from the edge of the screen, while if 1, it will use the parent x position as a it's x value * <span style="color: gray;> {z} </span>- Z spawn position, defaults to 0. Accept decimals. * <span style="color: gray;> <span style="color: gray;>{y} </span></span>- Y spawn position, defaults to 0. Accept decimals. * {direction} - direction of the spawn. According to the source, defaults to DIRECTION_RIGHT. If relative is 0, if will default to DIRECTION_RIGHT, but if relative is 1, it will uses it's parent direction. * {ptype} - Defaults to 0. If it has any value other than 0, the projectile is given a default name of "shot" and a model index of -1 as opposed to the parent model's predefined knife or pshot index. Best left ignored. * {type} - "0" - will use "knife' behaviour. "1" will use "bomb" behaviour (and ignores the ptype above). defaults to 0 * {map} - map of the spawned entity, defaults to 0 Usage: <pre>@cmd projectile 0 "nameoftheprojectile" 20 1 30 0 0 0</pre> ==Predefined Script Main Functions== '''void main() {}''' ** This is the main function for every script. main() is the main caller '''void ondestroy() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is killed or if in update.c/updated.c when close the engine. **Use this func to free your arrays/sprites for example '''void oncreate() {}''' **Useful in update.c/updated.c script or in ondrawscript/updatescript/script events. **This function is called when the entity is created or if in update.c/updated.c when start the engine. **Use this func to init you vars for example ==Event Scripts== The following is a list of event scripts. An event is essentially what it sounds like; an event that occurs while the OpenBOR engine is running. Pressing the attack key for example, is an event. OpenBOR includes the ability to define a specific script for many of these events. Careful use of this feature enables scripting extremely powerful features that use the bare minimum of resources. ==Global Events== The following events are as the name implies, global. The scripts are therefore predefined. To use a global script, simply create the relevant script file and place it in data/scripts. '''endlevel.c''' * Any level ends. '''join#.c''' * Corresponding player# (1-4) joins a game in progress. '''key#.c''' * Corresponding player# (1-4) presses or releases a key. '''keyall.c''' * Any player presses or releases a key. * player: Player index (0-3). '''level.c''' * Any level begins. '''loading.c''' * Any loading bar appears on the screen. Useful to make custom loading bars. '''pdie#.c''' * Corresponding player# (1-4) dies. '''respawn#.c''' * Corresponding player# (1-4) respawns after death. '''score#.c''' * Score changes for corresponding player# (1-4). '''timetick.c''' * Each tick of the game timer. * time: Current time value. '''update.c''' * Engine starts update cycle. '''updated.c''' * Engine completes update cycle. ==Level Events== Level events are tied to a specific level. To define a level script, add the desired event into the level.txt, followed by a path to the script file. '''keyscript#''' * Corresponding player# (1-4) presses or releases a key during this level. * player: Player index (0-3). '''spawnscript''' * Entity is spawned into play. This script is defined on a spawn by spawn basis (similar to Alias or Health), and a single spawn may have multiple spawnscripts if desired. * self: Caller. '''updatescript''' * Works in the same way of engine updatescript, but tied to a specific level. Runs in every tick, so use with caution. ==Entity Events== The following events are all entity specific. To define an entity event script, add the desired event name into the model header, followed a path to the script file. '''animationscript {path}''' * This command defines which animation script to call functions from * At least one function should be called if an animation script is declared (why bother declaring if it's not used) <pre> ==For script coding reference== Entity changes animation frame. self: Caller. animnum: Animation ID. frame: Animation frame. Animation scripts are a bit unique in that there is no need to include a main() function. Instead, you may add functions to be executed on call, or insert code directly into model files as shown below: @script ... @end_script - These two commands are used in tandem; by placing them directly within a model's animations you can insert script. You cannot define functions within the script insert as it is parsed to part of a function main(), but you can execute functions already defined. Note that regardless of which frame in the animation @script/@end_script tags are placed, the code will be evaluated on every frame. @cmd {name} {argument1} {argument2}... - This command will parse the expression into a function call, like name(argument1, argument2, ....). The function can either be a system function or user defined function. This means you can define functions in the animation script file, and then execute it here. @cmd is evaluated once when the animation frame immediately following the tag is reached. Multiple @cmd tags may be used. Notice: Arguments may not have spaces, use _ instead. If it is a string, enclose it with quotes: "thevalue".</pre> '''didblockscript {path}''' * This command defines which script is run when entity successfully blocked an attackdidhitscript {path} * This command defines which script is run when entity successfully attack <pre> ==For script coding reference== self: Caller. attacker: Entity attempting attack. damage: Amount of intended damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''didhitscript {path}''' * Entity's hits another entity normally, or entity is an item type being retrieved. <pre>self: Caller. damagetaker: Recipient of attack or item. damage: attack damage. "drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. blocked: Receiving entity did (1) or did not (0) block attack.</pre> '''keyscript {path}''' * This command defines which keyscript is run when entity is active * Only works on player type * Script is run when respective player presses or releases a key <pre> ==For script coding reference== self: Caller. player: Player index (0-3).</pre> '''inholescript {path}''' * This command defines which script is run when entity is in a hole <pre> ==For script coding reference== self: Caller. height: hole height. index: hole index. depth: hole depth. type: hole type (Integer). </pre> '''onblockascript {path}''' * This command defines which script is run when entity is blocked by ceiling or IOW hitting head * Must have 'height' (see above) set before entity could hit his/her/its head on platform or ceiling <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockpscript {path}''' * Works identically to onblockwscript, but for platforms. Provides the following local vars: self, plane, platform entity. '''onblocksscript {path}''' * This command defines which script is run when entity is blocked by screen edge <pre> ==For script coding reference== self: Caller.</pre> '''onblockoscript {path}''' * This command defines which script is run when entity is blocked by obstacles <pre> ==For script coding reference== self: Caller. obstacle: Entity blocking caller.</pre> '''onblockWscript {path}''' * This command defines which script is run when entity is blocked by walls <pre> ==For script coding reference== self: Caller. plane: Plane of movement blocked. 1 = X 2 = Z height: Height of blocking wall. index: wall ID</pre> '''onblockzscript {path}''' * Each update while entity is blocked by the Z boundary. <pre>self: Caller.</pre> '''ondeathscript {path}''' * This command defines which script is run when entity dies * Any cause of death will do including falling to holes <pre> ==For script coding reference== Immediately after takedamage when incoming damage is sufficient to kill entity. self: Caller. attacker: Entity causing damage. damage: Amount of unmodified damage. attacktype: Type of damage. drop: Knockdown power of damage. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''ondoattack {path}''' * Engine confirms an attack hit. Runs on both Attacker AND Defender (Defender is called first, then Attacker). Takes place after engine performs hit confirmation, but before hit handling (pain, blocking, etc.) takes place. By setting variant lasthitc to 0, you can cancel engine's hit handling. <pre> ==For script coding reference== self: Caller. other: When called on attacker, this recipient of attack. When called on defender, this is the attacker. damage: attack damage. drop: knockdown power. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack. which: 0 = Caller is defender. 1 = Caller is attacker. attackid: Current attack ID.</pre> '''onfallscript {path}''' * This command defines which script is run when entity is falling <pre> ==For script coding reference== Entity is put into fall state. Fires immediately after engine applies normal fall values. self: Caller. attacker: Entity causing knockdown. damage: Amount (if any) of unmodified damage at time of knockdown. drop: Knockdown power of attack instigating fall. attacktype: attack type, see 'openborconstant'. noblock: block break force of attack. guardcost: Guardcost of attack. jugglecost: Jugglecost of attack. pauseadd: Pause value of attack.</pre> '''onkillscript {path}''' * This command runs immediately before the entity is destroyed. '''onmodelcopyscript {path}''' * This command defines which script is run when entity change its model (weapon). This should be used in weapon models whenever you have spawn scripts since there is no spawn in weapon models. <pre> ==For script coding reference== self: Caller (the new model). old: previous model. void old = getlocalvar("old"); void self = getlocalvar("self");</pre> '''onmovexscript {path}''' * This command defines which script is run when entity is moving in X axis ''' onmovezscript {path}''' * This command defines which script is run when entity is moving in Z axis '''onmoveascript {path}''' * This command defines which script is run when entity is moving in Y axis (there's no A axis BTW :) ) '''onpainscript {path}''' * Immediately after entity is assigned pain animation and status. <pre>self: Caller. attacktype: Attack type triggering pain status. reset: Pain reset status (unknown function).</pre> '''onspawnscript {path}''' * This command defines which script is run when entity is spawned and respawned (for players) * If there is spawnscript (see 'Level Objects' below) declared for this entity, onspawnscript will be run first. '''ondrawscript {path}''' * this command define which scrip runs when the entity's sprite is drawn to screen. '''script {path}''' * This command defines which update script is run when entity is active * Update script is script which is run every engine cycle '''takedamagescript {path}''' * This command defines which script is run when entity receives attack. It doesn't matter how much damage entity takes though. * This script is also run on final blows '''thinkscript {path}''' * This command defines which script is run when entity thinks. <pre> ==For script coding reference== self: Caller.</pre> ==Key Scripts== Key scripts can be extremely powerful, but if not used properly will prove equally frustrating. Keep in mind the following when creating your key scripts: First, it is important to remember that key scripts fire both on press AND release of a key. This means a single key press actually runs a given keyscript twice; once when a player presses the key and again when he/she lets go. Make sure to account for this in your scripts or you will receive unexpected results. The ''playerkeys()'' function allows easy differentiation between press or release. Another consideration is to know the order in which key events run. If you have multiple key scripts overlapping each other, it is vital to know and account for the order in which the engine will process each. From first to last: #Level keyscript# #Entity keyscript #Global key#.c #Global keyall.c #Default key action. Another facet to keep in mind is the use of AI Flags and the ''takeaction()'' function. Without them the engine may override your scripted command milliseconds before it has a chance to occur. A common example would be trying to execute a custom attack while walking. Simply setting your desired animation won't be enough because the engine will set the walk animation right back. But by including the correct caveat functions in your script, the engine will "wait" and execute the desired actions properly. While fairly obvious, you should keep in mind the key event itself should be canceled when you are finished with it. Otherwise the engine will still run the key's default action immediately after all key scripts are complete. While in rare cases this might be useful, in most it will at best override your intended action and at worse produce a bug or crash. ==Script Reference== By uTunnels A script contains an interpreter to parse from text and execute the code. It can be loaded from a text file. A script also contains a local variant list. If the script is executed, the immediate code(those outside any functions) will be executed and function main will be called one time. The script will be reseted before next executation, so all script variants will lost, but the variants in local variant list will not been deleted, they are useful to store values. '''Syntax''' Similar to c syntax. Some differences: * Ignore types. int long char void ... will be treated as the same thing, they only tell the engine it is a data type. And a function can return a value no matter you set void type before it. * #include is available, and #define is available in builds after 2936 and #import. No other preprocessor directives are supported. * String concatenation. You can use + operator to strings, "string1" + "string2" returns "string1string2". * Assignment. The right variant's value and type will be copied to the left variant. No type checking, so be careful. From r4403 are valid multiple assignment like: x = y = 1; '''Available operators:''' # + # - # * # / # % # = # += # -= # /= # *= # %= # ! (it works for constants too from r4340+) # == # || # && # != # > # < # >= # <= # ~ (from r4316+) # ^ # | # & # << # >> # <<= (from r4316+) # >>= (from r4316+) # &= (from r4316+) # |= (from r4316+) # ^= (from r4316+) '''Available identifiers: ''' # do # while # for # break # if # else # switch # case '''Math Functions: ''' #pow({double}, {double}) #asin({double}) #acos({double}) #atan({double}) #ssin({double}) // Not approximated. #scos({double}) // Not approximated. #sin({double}) // approximated. #cos({double}) // approximated. #trunc({double}) #round({double}) ===Script Variants=== They contain values that can be used by script. They have 5 data types, but the script engine dont check them when they are defined, until they are used by any functions. ~Empty type: If a variants is defined but not initialized, it is an empty variant. So functions return an empty variant, so you can check if the function returns a valid value. ~Integer type: These variants can be initialized from integer constants, e.g., 123, -20 ..., 0x986AD3 ~Decimal type: These variants can be initialized from decimal constants, e.g., 0.3, -2.6666 ... ~String type: These variants can be initialized from string constants(limited to 63 characters), e.g., "hello", "__abcd.efg\n", 'c'... ~Pointer type: These variants can not be initialized from constants, they are used to store handles returned from function calls. Notice: string + string = string, integer +-*/% decimal = decimal, ===Local variants=== Each script can define its own variants by give it a unique name and a value. They wont be deleted when the script finishes executing and they live as long as the script itself. These variants cant be used by other scripts. ===Global variants=== The engine also has global variants. These variants can be used by all scripts. Each variant still must have a unique name, so you can retrieve it by name later. ===Functions=== You can define functions. Syntax is like this: <nowiki>type functionname([type argument1, type argument2, type argument3, ....]) { function body .... .... [return value] .... }</nowiki> Yeah, same as a c function, here is an example: <nowiki>int max(int a, int b) { if(a>b) { return a; } else { return b; } } </nowiki> ==Arrays== OpenBOR Script has a array support. There are 2 types. Numeric and Literal arrays. Numeric is set(array,0,value). Literal is set(array,"label",value). Here all functions. '''array(size)''' * size is the initial size of array '''size(array)''' * get the array size * from r4183+ it retrieve literal array size too '''get(array,index)''' * get the value in the index '''set(array,index,value)''' * set the value in the index '''delete(array, index)''' * delete the value in the index and resize the array * dynamically remove an array element * you can use set(array,index,NULL()) to delete the value without resizing the array '''add(array, index, value)''' * add an element in the index and resize the array (+1) * you can use set(array,index,value) but add() func is useful to add an element betwewn existent indexes '''next(array)''' * move the pointer from current literal position to next position '''previous(array)''' * move the pointer from current literal position to previous position '''reset(array)''' * reset the pointer incremented by next (in literal arrays) to first position '''value(array)''' * in literal arrays, it retrieve the value in the current position '''key(array)''' * in literal arrays, it retrieve the key value/label in the current position '''islast(array)''' * in literal arrays, it returns 1 if current pointer is on last element of literal array, otherwise it returns 0 '''isfirst(array)''' * in literal arrays, it returns 1 if current pointer is on first element of literal array, otherwise it returns 0 '''free(array)''' * free an allocated array * you must free an array somewhere, to avoid memory issues ==Filestream== Filestreams are functions to write/read a file. A filestream is an indexed file so when you open a file the file is saved in a index. '''openfilestream(path,location)''' * path is the string path of a file, ex.: "data/scripts/file.txt" * location is an optional value (default 0). if location is 1, openfilestream open a file with base the openbor saves path * it returns filestreamindex '''closefilestream(filestreamindex)''' * close a opened file handler '''getfilestreamline(filestreamindex)''' * it returns the string line in current position of the indexed opened file * filestreamindex is the indexed opened file '''getfilestreamargument(filestreamindex,argument,type)''' * it returns the value from file, at the position * filestreamindex is the indexed opened file * argument: is a int. if the returned string contains spaces or tabs it retuns the argument number x. example: getfilestreamargument() reads the string "RYU 200 points" I can read this line with: name = getfilestreamargument(filestreamindex,0,"string"); value = getfilestreamargument(filestreamindex,1,"int"); unit = getfilestreamargument(filestreamindex,2,"string"); * type: this is the argument type. Types are: "int", "float", "string", "byte" * if you set type "byte" the argument parameter is ignored '''filestreamnextline(filestreamindex)''' * increase pointer of filestreamindex opened file to next line from position '''getfilestreamposition(filestreamindex)''' * it returns the file pointer at the position '''setfilestreamposition(filestreamindex,position)''' * it sets the pointer of filestreamindex file to position '''filestreamappend(filestreamindex,value,write_type,value_type)''' * it writes a value in filestreamindex file in the buffer * value is the string or number that you want to write * write_type: is set 0, it appends a NULL char and "\r\n", 1 it appends a NULL char, otherwise it appends just the value * value_type: optional, if is "byte" you can write a byte value * examples: filestreamappend(savefile, 200, 2, "byte") '''createfilestream()''' * it create a filestream and returns filestreamindex '''savefilestream(filestreamindex,filename,pathname,type)''' * it saves buffer to file * file: file handler * filename: filename string * pathname: optional, if set use pathname otherwise use saves openbor path * type: optional, is set "byte" it writes a byte (no newline at EOF) * examples: savefilestream(savefile, "testwrite.txt", 0, pathname, "byte") ==Predefined Script Functions== The following is a list of the predefined script functions: '''isempty(variant)''' * Test if a ScriptVariant is an empty value. * Return 1 if it is an empty value, 0 if it isn't. '''NULL()''' * Return an empty value. You can use expression "variant == NULL()" to test if the variant is an empty value, it has the same effect with "isempty(variant)". '''getglobalvar(varname)''' * Return a global variant by name. If the value is not found, will return an empty value. * See 'global variants'. '''setglobalvar(varname, value)''' * Set a persistent global variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'global variants'. * Notice: It is important to remove unused global variants since there's a limit in amount (see above). '''getlocalvar(varname)''' * Return a local variant by name. If the value is not found, will return an empty value. * See 'local variants'. '''setlocalvar(varname, value)''' * Set a persistent local variant's value by name. If the value is empty, the variant will be deleted. * Return 1 if succeeded, 0 if failed. * See 'local variants'. * Notice: It is important to remove unused local variants since there's a limit in amount (see above). '''clearglobalvar()''' * Clear up all global variants. * Return: none * You can use it when a level starts or ends to save memory. '''clearlocalvar()''' * Clear up local variants. Only affect current script, though. * Return: none '''getindexedvar(int index)''' * Return a indexed global variant. '''setindexedvar(int index, value)''' * Give value to a indexed global variant. '''getscriptvar(int index)''' * Return a indexed script variant. '''setscriptvar(int index, value)''' * Give value to a indexed script variant. '''getentityvar(entity, int index)''' * Return a indexed entity variant. '''setentityvar(entity, int index, value)''' * Give value to a indexed entity variant. '''openborvariant(varname)''' * Return a openbor variant by name. * Names available: **”background", - is the BG used in a level **"blockade", - Limit x scroll back **"branchname", - Gets level branch name. Works ONLY if you touch the item to branch and gets reseted once you leave the stage. **"cheats" - TRUE if cheats are activated, otherwise FALSE. **"count_enemies", - counts how many enemies are active **"count_entities", - counts how many entities are active **"count_npcs", - counts how many npc are active **"count_players", - counts how many enemies are active **"current_branch", - Gets the current branch name. **"current_level", - Level index of current set, start from 0. **"current_palette", - gets current system palette **"current_scene", - gets current scene **"current_set", - Current difficulty set index, start from 0. **"current_stage", - Stage index of current set, start from 1. **"effectvol", - gets Sound fx volume **"elapsed_time", - gets the elapsed time until the moment **"ent_max", - get the maximum number of entities **"freeram", - gets the ammount of free ram **"game_paused", detects if the game is paused **"game_speed", detects the game speed **'game_time", detects the stage time. (4456+) <pre>int game_time = Openborvariant(“game_time”); changeopenborvariant(“game_time”, game_time); Acceptable range is 0-99. Any value exceeding range in either direction will be overwritten to nearest acceptable value on the next engine cycle. </pre> **"gfx_x_offset", - Enable X offset adjustment by modders. X coords of the screen. **"gfx_y_offset", - Enable Y offset adjustment by modders. Y coords of the screen. **"gfx_y_offset_adj", - is the shift relative to gfx_y_offset. **"hresolution", - Get screen width (Horizontal resolution) **"in_cheat_options", - detects cheat options **"in_control_options", - detects control options **"in_gameoverscreen", - detects GAME OVER screen **"in_halloffamescreen", detects HALL OF FAME screen **"in_level", Whether you are in a level (e.g., select screen is not a level). **"in_load_game", - detects LOAD GAME screen **"in_menuscreen", - detects MENU screen **"in_new_game", - detects NEW GAME screen **"in_options", - detects OPTIONS screen **"in_selectscreen", detects CHARACTER SELECT screen **"in_showcomplete", detects COMPLETE SCREEN screen **"in_sound_options", detects SOUND OPTIONS screen **"in_start_game", detects GAME OVER screen **"in_system_options", detects START GAME option **"in_titlescreen", detects TITLE screen (the one with PRESS START) **"in_enginecreditsscreen", detects if the engine's credits is displayed, but placed the variables for it in the shutdown command so that it can be called for even if the credits is not displayed. **"in_video_options", detects VIDEO OPTIONS screen **"lasthita", - Same of lasthity (<span style="color: red;>DEPRECATED</span>) **"lasthity", - Get Y axis of last hit **"lasthitc", - Confirms the last hit **"lasthitt", - is the last hit type (ex. ATK_NORMAL) **"lasthitx", - Get X axis of last hit **"lasthitz", - Get the Z value of last hit **"levelheight", - Gets the level height (set on the LEVELS.txt) **"levelpos", - Gets the curretn position on the level **"levelwidth", - Gets the total level width (how long is the level) **"lightx", - Gets the Light X value **"lightz", - Gets the Light Z value **"maxanimations", - gets the maximum number of animations **"maxattacktypes", - gets the maximum number of attack types **"maxentityvars", - gets maximum number of variables in each entity which is accessible by index **"maxglobalvars",- gets maximum number of global variables which is accessible by name. **"maxindexedvars", - gets maximum number of global variables which is accessible by index. **"maxplayers", -gets how many players could play at same time **"maxscriptvars", - gets maximum number of variables in each script which is accessible by index. **"models_cached", - gets the ammount of cached models **"models_loaded", - gets the ammount of loaded models **"musicvol", - gets the music volume **"nofadeout", - controls if the the screens fades out when you finish the current level **"nogameover", // don't show gameover (4396+) **"nohof", // don't show hall of fame before gameover (4396+) **"nojoin", - controls if the other players can join the game **"nopause", - controls if you can or cannot pause the game **"nosave", - controls if the game will be saved or not **"noscreenshot", - controls of you can take snapshots or not inside the game **"noshowcomplete" // don't show complete screen after NEXT (4396+) **"numbasemaps", // number of basemaps in the current level (4396+) **"numholes", // number of holes in the current level (4396+) **”numlayers", // number of layers in the current level (4396+) **"numpalettes", - gets the amount of palette from an entity **"numwalls", // number of walls in the current level (4396+) **"pakname", - gets the name of the game .pak **"pause", - detects if the game is paused **“pixelformat", - detects the pixel format (8 bit ,16bit, 32bit) **"player", - detects if the entity is a player **"player1", - detects the player 1 **"player2", - detects the player 2 **"player3", - detects the player 3 **"player4", - detects the player 4 **"player_max_z", - gets the maximum z position of the stage (how much "downward" on the stage an entity can go to). **"player_min_z", - gets the minimum z position of the stage (how much "upward" on the stage an entity can go to). **"porting" - gets the console version (4396+) **"sample_play_id", - is the last sound ID played (useful to stop the last sound played for example) **"scrollmaxx", - max scroll size that a level can scroll when you walk in X axis **"scrollmaxz", - max scroll size that a level can scroll when you walk in Z axis **"scrollminx", - min scroll size that a level can scroll when you walk in X axis. Example "scrollmaxx-scrollminx = 0" if you level has the same length of the game resolution (the level doesn't scroll) **"scrollminz", - min scroll size that a level can scroll when you walk in Z axis. **"self", - <span style="color: red;>DEPRECATED</span>. Is a global pointer in the engine code that refers to entity currently being updated. It's used by several internal functions and is essential to the engine. **"shadowalpha", - gfxshadow alpha mode **"shadowcolor" - gfxshadow color index. **"skiptoset", - Useful to change the active set (difficult). **"slowmotion", - detects it the slowmotion is active. Useful to detect boss kill (if the slowmotion isn't disabled) **"slowmotion_duration", - detects the duration of the slowmotion **"smartbomber", - detects if the player's special is a "smart bomb" which damages all onscreen enemies, regardless of position. **"soundvol", - controls the sound (samples) volume **"textbox", - is the textbox entity **"ticks", - is the MAIN time count like "elapsed_time" but is the elapsed time from engine run. Ticks is the time passed from engine run. **"totalram", - gets the total RAM available **"usedram", - gets the total used RAM **"vresolution", Get screen height (Vertical resolution) **"viewporth", - Height value for scrolling backgrounds/foregrounds **"viewportw", - Width value for scrolling backgrounds/foregrounds **"viewportx", - X value for scrolling backgrounds/foregrounds **"viewporty", - Y value for scrolling backgrounds/foregrounds **"vscreen", - allocated MAIN screen handler **"waiting", - is a var that is 1 if player waiting in a stage (set by wait at in level#.txt) **"xpos", - Level coords in x position, count from the left side of panels. **"ypos", - Level coords in y position, count from the top of panels. '''rand()''' * retrieve a random number ±X. '''srand(seed)''' * set a seed for random number generator '''drawstring(int x, int y, int font#, text, layer)''' * Draw the text in (x, y) of the screen, with font specified. * This method is costy, because each character is a sprite. And to prevent blinking, have to put this function in an update script (a script that runs each game loop). * layer is the z position '''getplayerproperty(playerindex, propname) / changeplayerproperty(playerindex, propname, value)''' * Get a player's property by name. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: ** "colourmap" - This is the map for the player ** "combokey" - This is the key pressed to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "combokey", getplayerproperty(0, "combostep")) ** "combostep" - This is the step (integer number) from 0 to x that define the step move in a combo ** "credits" - Credits left ** "disablekeys" - This is a flag. these are the keys that you can disable from input. ** "ent" - The entity of the player ** "entity" - The entity of the player ** "hasplayed" - This variable assumes 1 s the player has played at least once. useful for the custom HUD ** "hmapl" - This is the start index of hidden map. You can retrieve this when you joining too! ** "hmapu" - This is the end index of hidden map. You can retrieve this when you joining too! ** "inputtime" - The time when you press a key to make a combo, you need a supplementar param to use it: "combostep". Example: getplayerproperty(0, "inputtime", getplayerproperty(0, "combostep")) ** "joining" - This is 1 if tha player joining to play. Useful for custom HUD ** "keys" - This is a flag. These are the total keys pressed. ** "lives" - Lives left ** "mapcount" - Map number of the player. You can retrieve this when you joining too! ** "name" - The name of player ** "newkeys" - This is a flag. These are the new keys pressed in current frame ** "numweapons" - It retrieves the number of weapon of the player. You can retrieve this when you joining too! ** "playkeys" - This is a flag. These are the keys to move the character in the level ** "releasekeys" - This is a flag. These are the keys released in the current frame ** "score" - Score is ...hmm, score. From 0 to 999999999 ** "spawnhealth" - Initial health of player ** "spawnmp" - Initial MP of player ** "weapnum" - This is the weapon index ** "weapon" - This is a write only value. This is the weapon index. you need a supplementar param to use it: anim_flag. Example: changeplayerproperty(0, "weapon", 2, 0) to change to weapon 2 and anim_flag 0 *** anim_flag: if set to 1 for scripted midair weapon changing, default 0 * Property names: **"model" - Change the model by name, follow the name is another argument, 0 means keep current animation, 1 means reset to default. **"weapon" - Change weapon by index. **"maxhealth" - Max health. **"health" - Current HP left, if it is greater than max, will be set to max. **"maxmp" - Max MP. **"mp" - Current MP left, if it is greater than max, will be set to max. **"name" - Name, or we say alias. **"position" - Follow by x, z, a, do a nice warp. **"base" - Base altitude of the entity. **"velocity" - Follow by speed in x, z, a direction, entity will move in this speed each A.I. loop. These values can be modified by A.I. functions, so it is almost useless until it is a non-AI controlled character,e.g., type none. **"defense" - Change one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the defense factor, e.g. 1.0 means reduce damage of this type by 100%. **"offense" - Change one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant'), and a decimal value specifies the offense factor, e.g. 1.0 means increase attack power of this type by 100%. **"nograb" - An integer, whether this entity can be grabbed, see nograb/cantgrab property of entity. **"map" - Integer that sets color remap of entity. 0 = default, 1 = first remap, and so on. Icons are not affected. **"stealth" - Entity's stealth factor. **"detect" - Entity's stealth detect factor. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"attacking" - Enttiy's attack box status. When 0, attack box will not hit other entities. **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"drain" - Follow with {drain}, {draintime}, {drainamt}, {drainrate} to change drain properties. **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"animhits" - the internal hit counter for current animation. '''tossentity(entity, height, speedx, speedz)''' * Just like a jump, 'toss' the entity to the air. * 'entity' is the handle of that entity. * 'height' is the jump height. * 'speedx' is the speed in x direction. * 'speedz' is the speed in z direction. '''setspawnentry(propname, values)''' * Set a property of the spawn entry. These's a global spawn entry, you can change its properties so you can use it to spawn an entity. * 'propname' is the property's name. Check spawn command in level's .txt. * 'values' is new value. * Property names: All supported in a spawn entry, except 2p/3p/4pspawn. '''clearspawnentry()''' * Clear up the global spawn entry. '''spawn()''' * Use the global spawn entry to spawn an entity. * Return the entity. '''openborconstant(name)''' * Get a constant or system value by name. * Return the value or just an empty variant if the name is not supported. Names * ''Types'' and ''subtypes'' for entity. Not all are listed, and not all listed are useful right now. *Type **"TYPE_NONE" **"TYPE_PLAYER" **"TYPE_ENEMY" **"TYPE_ITEM" **"TYPE_OBSTACLE" **"TYPE_STEAMER" **"TYPE_SHOT" **"TYPE_TRAP" **"TYPE_TEXTBOX" **"TYPE_ENDLEVEL" **"TYPE_NPC" *Subtype **"SUBTYPE_NONE" **"SUBTYPE_BIKER" **"SUBTYPE_BOOMERANG" **"SUBTYPE_NOTGRAB" **"SUBTYPE_ARROW" **"SUBTYPE_TOUCH" **"SUBTYPE_WEAPON" **"SUBTYPE_NOSKIP" **"SUBTYPE_FLYDIE" **"SUBTYPE_BOTH" **"SUBTYPE_PROJECTILE" **"SUBTYPE_FOLLOW" **"SUBTYPE_CHASE" *Attack types **"ATK_NORMAL" **"ATK_NORMAL2" **"ATK_NORMAL3" **"ATK_NORMAL4" **"ATK_BLAST" **"ATK_BURN" **"ATK_FREEZE" **"ATK_SHOCK" **"ATK_STEAL" **"ATK_NORMAL5" **"ATK_NORMAL6" **"ATK_NORMAL7" **"ATK_NORMAL8" **"ATK_NORMAL9" **"ATK_NORMAL10" **"ATK_ITEM" = attack type when hit by an "itembox" from an item. **"ATK_LAND" = is for damage taken when damage_on_landing is applied, or from the engine's default Throw system. **"ATK_LIFESPAN = attack type which happens when the LIFESPAN value is reached **"ATK_PIT" = its an attack type which happens when you fall on a hole **"ATK_TIMEOVER = attack type which happens when you got a time over *Level directions. **"SCROLL_RIGHT" **"SCROLL_DOWN" **"SCROLL_LEFT" **"SCROLL_UP" **"SCROLL_BOTH" *Direction of an entity. (4194+) **DIRECTION_LEFT **DIRECTION_RIGHT *Direction adjustment property for binding and attack hits. (4194+) **DIRECTION_ADJUST_LEFT **DIRECTION_ADJUST_OPPOSITE -- Force target's direction to opposite of owner's. **DIRECTION_ADJUST_NONE **DIRECTION_ADJUST_RIGHT **DIRECTION_ADJUST_SAME -- Force target's direction to same of owner. * Animation id. **"ANI_IDLE" **"ANI_WALK" **"ANI_JUMP" **"ANI_LAND" **"ANI_PAIN" **"ANI_FALL" **"ANI_RISE" **"ANI_ATTACK1" **"ANI_ATTACK2" **"ANI_ATTACK3" **"ANI_ATTACK4" **"ANI_UPPER" **"ANI_BLOCK" **"ANI_JUMPATTACK" **"ANI_JUMPATTACK2" **"ANI_GET" **"ANI_GRAB" **"ANI_GRABATTACK" **"ANI_GRABATTACK2" **"ANI_THROW" **"ANI_SPECIAL" **"ANI_FREESPECIAL" **"ANI_SPAWN" **"ANI_DIE" **"ANI_PICK" **"ANI_FREESPECIAL2" **"ANI_JUMPATTACK3" **"ANI_FREESPECIAL3" **"ANI_UP" **"ANI_DOWN" **"ANI_SHOCK" **"ANI_BURN" **"ANI_SHOCKPAIN" **"ANI_BURNPAIN" **"ANI_GRABBED" **"ANI_SPECIAL2" **"ANI_RUN" **"ANI_RUNATTACK" **"ANI_RUNJUMPATTACK" **"ANI_ATTACKUP" **"ANI_ATTACKDOWN" **"ANI_ATTACKFORWARD" **"ANI_ATTACKBACKWARD" **"ANI_FREESPECIAL4" **"ANI_FREESPECIAL5" **"ANI_FREESPECIAL6" **"ANI_FREESPECIAL7" **"ANI_FREESPECIAL8" **"ANI_RISEATTACK" **"ANI_DODGE" **"ANI_ATTACKBOTH" **"ANI_GRABFORWARD" **"ANI_GRABFORWARD2" **"ANI_JUMPFORWARD" **"ANI_GRABDOWN" **"ANI_GRABDOWN2" **"ANI_GRABUP" **"ANI_GRABUP2" **"ANI_SELECT" **"ANI_DUCK" **"ANI_FAINT" **"ANI_CANT" **"ANI_THROWATTACK" **"ANI_CHARGEATTACK" **"ANI_VAULT" **"ANI_JUMPCANT" **"ANI_JUMPSPECIAL" **"ANI_BURNDIE" **"ANI_SHOCKDIE" **"ANI_PAIN2" **"ANI_PAIN3" **"ANI_PAIN4" **"ANI_FALL2" **"ANI_FALL3" **"ANI_FALL4" **"ANI_DIE2" **"ANI_DIE3" **"ANI_DIE4" **"ANI_CHARGE" **"ANI_BACKWALK" **"ANI_SLEEP" **"ANI_FOLLOW1" **"ANI_FOLLOW2" **"ANI_FOLLOW3" **"ANI_FOLLOW4" **"ANI_PAIN5" **"ANI_PAIN6" **"ANI_PAIN7" **"ANI_PAIN8" **"ANI_PAIN9" **"ANI_PAIN10" **"ANI_FALL5" **"ANI_FALL6" **"ANI_FALL7" **"ANI_FALL8" **"ANI_FALL9" **"ANI_FALL10" **"ANI_DIE5" **"ANI_DIE6" **"ANI_DIE7" **"ANI_DIE8" **"ANI_DIE9" **"ANI_DIE10" **"ANI_TURN" **"ANI_RESPAWN" * These are infact variable, but unchanged during a level. **"PLAYER_MIN_Z" **"PLAYER_MAX_Z" **"BGHEIGHT" **"MAX_WALL_HEIGHT" * These are the sound effects defined by the module and loaded at startup. **"SAMPLE_GO" **"SAMPLE_BEAT" **SAMPLE_BLOCK" **"SAMPLE_INDIRECT" **"SAMPLE_GET" **"SAMPLE_GET2" **"SAMPLE_FALL" **"SAMPLE_JUMP" **"SAMPLE_PUNCH" **"SAMPLE_1UP" **"SAMPLE_TIMEOVER" **"SAMPLE_BEEP" **"SAMPLE_BEEP2" **"SAMPLE_BIKE" '''playerkeys(playerindex, newkey?, key1, key2, key3, ...)''' * Check if a key is pressed by the player. * 'playerindex' is an integer count from 0, that is, 0 means 1p, 2 means 3p, etc. * 'newkey?', 0 if the keys are not new. * key names: **"jump" **"attack" **"special" **"esc" **"start" **"moveleft" **"moveright" **"moveup" **"movedown" **"screenshot" **"anybutton" * Any combination is allow, but no reason to use "anybutton" with others. * Return 1 only when all buttons in list are pressed, keep in mind. *NOTE* This method call is a bit buggy as of 8/8/2007. If not used in "key#.c" it will always return 0 unless newkey? = 0. If used to detect multiple keys, 1 will be returned if ANY of the specified keys are pressed. '''playmusic(name, loop)''' * Play a bor music. * 'name' is the path. * 'loop': 0 means dont loop, 1 means loop. '''playsample(sample, prioroity, lvolume, rvolume, speed, loop)''' * Play a defined sound sample. * 'sample' is a sample constant (see openborconstant()). * 'priority' is the playing priority. * 'lvolume' is left volume. * 'rvolume' is right volume. * 'speed' is the play speed. * 'loop': 0 = no loop, 1 = loop. To play a sound with normal defaults used by the engine, use the following settings (this will play the beat sound): 'playsample(openborconstant("SAMPLE_BEAT"), 0, 120, 120, 100, 0);' '''changepalette(index)''' * Change current palette to specified one. * 'index' is an integer, 0 means default palette, 1-? can be any palette you loaded with command palette in level's .txt. If it is out of range, default will be used. Only the onscreen entity's palette will change. Its icon (if any) will not. '''killentity(entity)''' * Kill the entity. * 'entity' is the entity you want to kill. * This method wont display the entity's death animation, or any animation for that matter; the entity is removed instantly. If you want to kill an entity with death animation, use damageentity(). '''damageentity(entity, other, force, drop, type)''' * Damage the entity. * 'entity' is the entity you want to damage. * 'other' who damage this entity, can be itself, if you specify a player's entity, score will be added. Default to the entity itself. * 'force' is the attack force. default to 1. * 'drop' is whether the attack knocks down the entity. * 'type' attack type, e.g., a shock attack or attack1-10, see openborconstant, the constants starts with 'ATK_' '''findtarget(entity, int animnum)''' * Returns handle of the nearest hostile entity. * 'entity' is the entity who?s nearest hostile you want to return. For example, if ?entity? is a PC, then the handle returned will be that of the nearest enemy character. * animnum - Animation id. Optional. If it is given, the range values of the animation will be used to test if the target is in range. Among other things, this is very useful for making range based or "guided" attacks. '''finditem(entity)''' ‘entity’ is the nearest item entity you want to return. The “finditem” works like “findtarget” and will return the closest item detected. Tip: You can use the “finditem” to detect other properties, like animation or position, and then use the “pickup” function only if a previous defined rule is reached. '''pickup(entity, item)''' entity – caller entity who will pick the item item – item to be picked by the entity This function will force the item to be taken no matter the distance, but it will only work for “valid” items that are on the screen. '''drawbox(x,y,width,height,z,color,alpha)''' * draw a filled box with specified position and size. * x,y: position values on screen * width,height: size values. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawline(x1,y1,x2,y2,z,color,alpha)''' * draw a line from (x1, y1) to (x2, y2) * x1, y1: position values of the start point. * x2, y2: position values of the end point. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. * return: none '''drawdot(x, y, z,color,alpha)''' * draw a dot at (x, y) * x, y: position values of the dot. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''rgbcolor(value1,value2,value3)''' * the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB). * ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B. This is the RGB form. * some devices read the color from left to right and the others on the contrary. * for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead. * To overcome these disadvantages of incompatibility is useful to use rgbcolor(). EXAMPLE: good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii '''allocscreen(width, height)''' * Create a screen, return the handle. Basically you should call it in levelscript, but it is up to you. Be sure to store the handle or if you lose it you will not be able to free it, so it will take up memory until shut down. You can exit the engine normally and check the log to see if you forget to releas some of them. '''drawlinetoscreen(screen, x1, y1, x2, y2, color, alpha);''' * Similar to drawline, use the screen instead of the sprite queue. And also: drawboxtoscreen(screen, x, y, width, height, color, alpha) drawdottoscreen(screen, x, y, color, alpha) '''free(handle)''' Release a object created by script engine, it is now only available for the handle created by allocscreen, until we add some other dynamic alloc methods. Basically you should call it in endlevelscript, but it is up to you. '''drawscreen(screen, x, y, z,alpha)''' * Draw current screen. * x, y: position values of the coordination. * z: depth value, similar to setlayer command or entities, check it for details. * color: color index in palette, check you palette. * alpha: alpha blending effect from 1 to 6, this parameter is optional. '''jumptobranch(name, immediate)''' * Go to branch by name. Branches is defined in levels.txt, check the manual for details. * name: the branch name, must be those defined in levels.txt * immediate: when set to 1, you will go to that level immediately if you are currently in a level, or else, you will still need to beat current level. '''bindentity(entity, target, int x, int z, int a, int direction, int bindanimation, int sortid)''' * Bind entity to target, so the target moves, the entity moves. * x, z, a: relative to target. * direction: 0 no change 1 same direction as target -1 opposite direction as target 2 always right -2 always left * bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match. * sortid: -1 by default. -1 means that the binded entity is on back the target. you can set 1 to show binded entity in front of target or you can use what-you-want value. * To unbind a entity, use bindentity(entity, NULL()); * Partial binding is now possible (4183+). Pass NULL() to any axis you do not want to bind. * Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4. '''changelight(int x, int z)''' * Change light direction for gfxshadow. * x, z: direction value, a positive x will make the shadow lean to the right, a positive z will make the shadow upward, or else they will be flipped. * Give 256 or -256 to z will make the shadow as long as its owner. * Try different values until you find the correct one. '''changeshadowcolor(int colorindex)''' * Change gfxshadow color. * Note, gfxshadow use alpha 2, same as shadow. '''changelevelproperty(name, propertyvalue)''' * Change a property value of current level, this function is not quite completed. * You need to provide at least two values (name and property value) * Some properties like "basemap", "wall" and "hole" needs more values. * Refer the manual for more information about each item. * Name can be: ** "basemap", ** "bgspeed"{float}, ** "cameraxoffset" {integer}, ** "camerazoffset"{integer}, ** "gravity" {float}, ** "hole", ** "maxfallspeed" {float}, ** "maxtossspeed" {float}, ** "quake" {integer}, ** "rocking" {integer}, ** "scrollspeed"{float}, ** "type"{string}, ** "vbgspeed", ** "wall", * ''Basemap'' has additional values (refer the manual for more information about Basemap): ** "map" {integer}, ** "x" {float}, ** "xsize" {float}, ** "z" {float}, ** "zsize" {float}, * ''Walls'' and ''Holes'' has additional values: ** "depth" {float}, ** "height" {float}, ** "lowerleft" {float}, ** "lowerright" {float}, ** "type" {integer}, ** "upperleft" {float}, ** "upperright" {float}, ** "x" {float}, ** "z" {float}, '''loadmodel(name)''' * "Load" a model that is currently set as "know" in models.txt. * "name" is the model's name. '''loadsprite(path)''' * Load a single sprite from the path specified and return the handle for later use. * You can free the sprite by calling script function free. * Notice, the sprite will never be free automatically by the engine until the engine is about to shutdown so you have to keep the handle and free it manually later. * Notice, the offset of the sprite will be always (0,0) like any regular icon and panel. * Notice, the sprite is completely new, so if the path is used by an entity, there's not side effects if the entity model is unloaded. '''drawsprite(sprite, int x, int y, int z, int sortid)''' * Draw a sprite. * Sprite must be a valid handle. * x, y are the draw position. * z is depth, sprite with a greater z value will appear above those with smaller z values. * If more than one sprites use same z value, you need sortid to sort them, also, a greater value makes the sprite appear above others. In most situations, just use 0. * See function setdrawmethod if you want to use special effects for the sprite. * Notice: the sprite handle must be valid, that means if the sprite is removed already, an error might happen. '''drawspritetoscreen(sprite, screen, int x, int y)''' * Draw a sprite to a screen. * sprite must be a valid handle. * screen must be a valid handle returned by allocscreen. * x, y are draw position. * See function setdrawmethod if you want to use special effects for the sprite. '''setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int colourmap, int fillcolour, int rotate, int rotateflip, int transparencybg)''' * Set drawmethod for an entity or define a global drawmethod for other script functions. * entity must be a valid entity handle or an empty value. * All other parameters are optional. * flag defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * scalex defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * flipx defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. * flipy defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. * shiftx defines how the sprite leans, like lightx in gfxshadow feature, in most situations you don't need this. * alpha defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * colourmap(entity only) defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * fillcolour is the colour used by the entire sprite. 0 means don't fill the sprites. * rotate is the rotate angle(clockwise), the range is from 0 to 359. * rotateflip(entity only) means whether the entity will flip its rotate direction if the facing is changed. * transparencybg(screen only) means whether the screen will use transparency colour. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''changedrawmethod(entity, propertyname, value);''' * Change drawmethod for an entity or define a global drawmethod for other script functions. * alpha, // Defines which alpha blending effect will be used. 0 means no alpha effect. -1 means the entity(if given) will use its own alpha value. * amplitude, // Sets the amplitude of sine wave for water effect * beginsize, // Sets size multiplier of upper border. The upper border should be smaller than lower one cause the former is farther * centerx, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * centery, // Sprite's X offset. For an entity's animations this is initially the same as the frame offset. Otherwise both is 0. * channelb, // Defines the value for the B (blue) channel * channelg, // Defines the value for the G (green) channel * channelr, // Defines the value for the R (red) channel * clip, // Accepts all clipping attributes at once. Leave it alone and use the individual clip attributes instead. * cliph, // Defines the width of the cropped area (horizontal) * clipw, // Defines the start point in x axis (horizontal) * clipx, // Defines the start point in y axis (vertical) * clipy, // Defines the height of the cropped area * enabled, // Redundant - both do the same thing. Use enabled. * endsize, // Sets size multiplier of upper border of Water mode * fillcolor, // Is the colour used by the entire sprite. 0 means don't fill the sprites. An integer value, from 0 to 255, specify a color index in your palette. It can be used with alpha, fill current frame with this color. You can either use a raw integer value or in R_G_B format, the later has better compatibility obviously. * flag, // defines whether the drawmethod is active, when set to 0, the drawmethod will not take effect. * fliprotate, // is binary value. When it is set to 1(should be only 0 or 1, not other values), the entity will change the rotate value when the direction is changed(entity's direction, if you use flipx for the frame, it is not affected), the rotate value will be 360-original, so * flipx, // defines whether the sprite will be flipped left/right. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped leftright. * flipy, // defines whether the sprite will be flipped top/bottom. 0 means don't flip and 1 means flip. An integer value, when set to 1, the frame will be flipped updown. * perspective, // Defines z depth effect it should have (Water mode) * remap, // Defines which colourmap will be used. 0 means no colourmap. -1 means the entity(if given) will use its current colourmap. * reset, // Resets all attributes to their default values. * rotate, // Is the rotate angle(clockwise), the range is from 0 to 359. * scalex, // Defines how the sprite will be stretch in x direction: sizex = original_sizex * scalex / 256 * scaley, // Defines how the sprite will be stretch in y direction: sizey = original_sizey * scaley / 256 * shiftx, // defines how the sprite leans, like lightx in gfxshadow feature * table, // Pointer to color table in use by sprite. As always, if you apply a color table with cells that don't line up with the sprite's original table, you'll get Rainbow Dash with a hangover. * tintcolor, // Will tint the sprite with given tintcolor, in alpha mode tintmode * tintmode, // Defines the tintmode * transbg, // Behavior of the transparent color. 0 = Display the transparent color. 1 = Do not display transparent color. It's more efficient to display the transparent color, so use this option where your module design permits. Good candidates are the last layer in backgrounds, certain panels, signs, and so on. * watermode, // Determines water effect. Currently there are 3 modes. * wavelength, // Determines length of sine wave in pixels. It's repeated since it's sine wave. Only apply if {watermode} is not 3 (see below) * wavespeed, // Determines the moving speed of sine wave. Only apply if {watermode} is not 3 (see below) * wavetime, // (elapsed_time + text_time) * wavespeed each time a layer in the level is drawn. Has no functionality, it's mostly a debugging tool. * xrepeat, // Determine how many times the image will repeat in X axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * xspan, // For background layers, controls x spacing. See xspan. * yrepeat, // Determine how many times the image will repeat in Y axis. Setting 0 will make layer not drawn at all (it will become palette holder). Setting -1 will make it repeat forever * yspan, // For background layers, controls y spacing. See zspan. * Notice: In 8bit mode, fillcolour is the index in palette, otherwise, it will be a RGB value which needs to be calculate first(no system functions available now). * Notice: For screen, transparency colour is the first colour in palette(8bit) or pure black colour(which is also 0). * Notice: If the entity parameter is an empty value, it will change the global drawmethod, and can be used by other script functions like drawsprite or drawscreen. '''playgif(path, int x, int y, int noskip)''' * Play a gif file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * x, y position of the gif animation, like 2nd and 3rd parameters of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: it needs some extra memory to play a gif file, about 75kb if the screen is 320x240/8bit. '''playwebm(path, int noskip)''' * Play a webm file as a cut scene, you can call it in game. * path, the gif file path, like first parameter of command animation in scene txt. * noskip, when set to 1, you can't press button to skip it. * Notice: path is required. All other parameters are optional, and default value is 0. * Notice: a webm is played ONLY if the device has the webm support. '''checkrange(entity, target, int animid)''' * Check if the given target is in range. Range, rangez, rangea of the specified animation will be used for checking. * entity - animation owner. Must be a valid entity handle. Required. * target - must be a valid entity handle. Required. * animid - animation id. Optional. If it is not given, current animation will be used. '''updateframe(entity, int frame)''' * This method update current animation's frame number, a replacement of changeentityproperty(..., "animpos"). '''performattack(entity, int anim, int resetable)''' * This method allow the entity to do an attack, not just give it attack animation. * anim - Optional. It stands for animation number, can be got by openborconstant. * resetable - Optional. If current animation number is same as this one, and resetable is 1, current animation will be reset or else, the anim will be ignored. * Notice: If you provide anim parameter, and this function is called in an animation script, you probably need to add a return behind it because the animation might be changed and the animation script will be re-called. '''executeanimation(entity, int anim, int resetable)''' * it works like performattack() but just you play an animation without animation loop. * This function is useful to avoid changeentityproperty(entity,"animation",value) loop issue! '''setidle(entity, int anim, int resetable, int stalltime)''' * This method change the entity back to idle status. * anim - same as above. Optional. You probably will use idle animation, but that is up to you. * resetable - same as above. Optional. * stalltime - how long will current idle status last, in game tick. 200 will be about 1 second. Optional. * Notice, idle status means the entity can change to other status automatically by the engine. So walk/run/idle can all be treated as idle. * Also notice, you can set velocity for the entity later to simulate walk/run. '''getentity(int index)''' * Return entity by index. * If this method succeeds it will return the entity handle, but be sure to check "exist" property by getentityproperty because it might be a dead one. If index is out of range, this function will return an empty value, make sure you check it if you are not sure. * The range is from 0 to MAX_ENTS-1, you can get MAX_ENTS by openborconstant("MAX_ENTS") * Notice, the entities are not always in same order, if you call it during a gameloop, it is safe, but if you use same index next time, the result might be different. * MAX_ENTS is a large number, but most mods only have few entities on screen, so you should use openborvariant("ent_max") instead, it is a variable, so make sure you get it in different game loop. '''recordinputs(value,pathname,filename)''' * This function allow you to rec/play your gameplay. It's a replay! Useful for attract mode for example. * pathname: is the pathname string. if set "" value (empty string) default pathname will be saves openbor path * filename: that you want to read/save * value: **0 to stop the rec/play **1 to rec **2 to play **3 to free (dont worry when you use 0 you free the buffer too). the 3 param is not really useful. usage: to rec: recordinputs(1,"","myrec.inp"); to play: recordinputs(2,"","myrec.inp"); to stop: recordinputs(0); to free: recordinputs(3); example: write in levelscript: recordinputs(1,"","myrec.inp"); if(playerkeys(0,1,"esc")) { recordinputs(0); } play at level.. press "esc" to terminate the rec. then change recordinputs(1,"","myrec.inp"); in recordinputs(2,"","myrec.inp"); to test and play the recorder gameplay! note: you need for a deterministic game and so is not allowed a custom seed. If you change anything in your mod or change the engine version you need to re-record the gameplay!! I raccomanded you to disable all keys during the gameplay with new playerproperty(pindex,"disablekeys") excluded keys to stop the gameplay. then reactivate the Keys. to disable keys just changeplayerproperty(pindex,"disablekeys",openborconstant("FLAG_START")+openborconstant("FLAG_ATTACK")); for example to re-enable keys just: changeplayerproperty(pindex,"disablekeys",0); '''getrecordingstatus()''' * use getrecordingstatus() to get the gameplay status 0 or 1 or 2 according to recordinputs() values ==Entityproperty== '''getentityproperty(entity, propname) / changeentityproperty(entity, propname, values)''' * Get an entity's property by name. * 'entity' is the handle of that entity. * 'propname' is the property's name. * 'value' is new value you want to set. * Property names: **"a" - Altitude (<span style="color: red;>DEPRECATED</span>) **"aggression" - **"aiattack" - **"aiflag" - **"aimove" - **"alpha" - Channel for sprite fusion. From 0 to 6. **"animal" - **"animating" - In return 0 if the entity isn't in animation (static frame), 1 if animation forward (from 0 to X) and -1 if animating backward (from X to 0). Example AI enemies when walking back have "animating" == -1. **"animation" - The handle of current animation. **"animation.handle" - **"animationid" - The id of current animation. It is an integer value, see 'openborconstant'. **"animheight" - **"animhits" - The internal hit counter for current animation. **"animnum" - Is the "animationid" **"animpos" - Frame position of current animation. **"animvalid" - It returns 1 if animation exists in entity.txt **"antigrab" - **"antigravity" - **"attackid" - **"attacking" - Entity's attack box status. When 0, attack box will not hit other entities. **"attackthrottle" - **"attackthrottletime" - **"autokill" - **"base" - Altitude base where is the entity on, if a equals base, this entity is in air. **"bbox" - **"blink" - **"blockback" - **"blockodds" - **"blockpain" - Entity blockpain property. If intended damage from blocked attack >= blockpain, entity will briefly twitch or play Blockpain animation if it has one. **"boomerang" - changeentityproperty(entity,"boomerang",acceleration,horizontal_distance) and getentityproperty(entity,"boomerang",flag) -> flag: 0 = acceleration, 1 = horizontal_distance **"boss" - **"bounce" - **"bound" - **"candamage" - **"chargerate" - **"colourmap" - **"colourtable" - **"combostep" - **"combotime" - **"custom_target" - If set it you can force an enemy to use it as target. **"damage_on_landing" - Damage that will be applied at end of a fall. If -1, entity will instantly recover at end of fall and play "land" animation if it has one. **"dead" - **"defaultmodel" - Model name base (no weapon name) **"defaultname" - Model name base (no weapon name) **"defense" - Return one of the defense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also 'changeentityproperty'). **"destx" - Destination of coord X for A.I. **"destz" - Destination of coord Y for A.I. **"detect" - Entity's stealth detect factor. **"direction" - Direction, 1 means left, 0 means right. **"dot" - **"dropframe" - **"edelay" - **"energycost" - **"escapecount" - **"escapehits" - **"exists" - Well, whether the entity is a valid one. **"facing" - **"falldie" - **"flash" - **"freezetime" - **"frozen" - **"gfxshadow" - This is the flag to set gfxshadow **"grabbing" - Entity currently held in a grab (if any). Only returns currently held entity. **"grabforce" - **"guardpoints" - **"hasplatforms" - It returns 1 if the entity you set is has a platform in current animation **"health" - Current HP left. **"height" - Height of a entity. If not set, you can't hit the latform with head. **"hitbyid" - **"hitheadplatform" - It returns the platform handler if the entity hit the platform with head and set the entity height > 0 **"hitwall" - It returns 1 while you hit a wall/obstacle/platform while y > base **"hmapl" - Start index of hidden maps that you set with hmap X Y. **"hmapu" - End index of hidden maps that you set with hmap X Y. **"hostile" - **"icon" - **"iconposition" - **"invincible" - **"invinctime" - **"jugglepoints" - **"jumpheight" - **"jumpmovex" - **"jumpmovez" - **"jumpspeed" - **"knockdowncount" - **"komap" - **"landedplatform" - It returns the platform handler where the entity is on if entity is on, otherwise it returns NULL() **"landframe" - **"lifeposition" - **"lifespancountdown" - **"link" - **"map" - Current color remap in use. 0 = default, 1 = first remap, and so on. **"mapcount" - Number of maps **"mapdefault" - **"maps" - **"maptime" - **"maxguardpoints" - **"maxhealth" - Max health. **"maxjugglepoints" - **"maxmp" - Max MP. **"model" - Model name. **"mp" - Current MP left. **"mpdroprate" - **"mprate" - **"mpset" - **"mpstable" - **"mpstableval" - **"name" - Current name, or we say alias. **"nameposition" - **"nextanim" - **"nextmove" - **"nextthink" - **"no_adjust_base" - **"noaicontrol" - **"nodieblink" - **"nodrop" - **"nograb" - **"nohithead" - set nohithead 1 in entity.txt and even if you set an height for the entity, if it hit a platform with nohithead param set to 1, the entity will not block with head by a platform. But this platform will be walkable however. default is 0 **"nolife" - **"nopain" - **"numweapons" - It returns the number of weapons of the entity. **"offense" - Return one of the offense factors of this entity. Follow by an integer specifies the attack type(see 'openborconstant', and also **'changeentityproperty'). **"offscreen_noatk_factor" - set the chance (you need 1.0) has the enemy to attack offscreen. if you set 1.0 (NO ATK FACTOR) the enemy will not attack offscreen **"offscreenkill" - set after how many pixels offscreen the enemy can die **"opponent" - Last entity interacted with (damaged, damaged by, grabbed, etc.). Essentially this returns whoever would be showing up on a player's enemy life meter, but works for all entities. **"owner" - **"pain_time" - **"parent" - **"path" - **"pathfindstep" - **"playerindex" - **"position" - **"projectile" - Entity's projectile (blasted or thrown) status. 0 = Normal, 1 = Blasted or thrown. **"projectilehit" - **"range" - **"releasetime" - **"running" - **"rush_count" - current rush count **"rush_tally" - max rush count **"rush_time" - how much time you have before rush has ended. **"score" - **"scroll" - **"seal" - Entity's seal property. Entity cannot perform any special with an energy cost >= seal property. **"sealtime" - The elapsed gametime when engine will reset seal property to 0. **"setlayer" - **"shadowbase" - **"sortid" - **"spawntype" - **"speed" - **"sprite" - **"spritea" - **"stalltime" - **"stats" - **"staydown" - **"staydownatk" - **"stealth" - Entity's stealth factor. **"subentity" - **"subject_to_basemap" - **"subject_to_gravity" - **"subject_to_hole" - **"subject_to_maxz" - **"subject_to_minz" - **"subject_to_obstacle" - **"subject_to_platform" - **"subject_to_screen" - **"subject_to_wall" - **"subtype" - Subtype, e.g., arrow, biker. It is an integer value, see 'openborconstant'. **"takeaction" - **"think" - **"thold" - **"throwdamage" - **"throwdist" - **"throwframewait" - **"throwheight" - **"tosstime" - **"tossv" - Toss velocity (jumping or falling). **"trymove" - **"type" - Type, e.g, enemy, player. It is an integer value, see 'openborconstant'. **"velocity" - Set the velocity. It accepts 3 params. NULL() is valid. **"vulnerable" - **"walkoffmovex" - **"walkoffmovez" - **"weapent" - **"weaploss" - It accepts to values, example: changeentityproperty(entity,"weaploss",1,0). For first value see weaploss {flag} for second set the flag active on/off **"weapnum" - Set/get the weapon index **"weapon" - Set/get the weapon index but it accepts a second param, anim_flag: if set to 1 for scripted midair weapon changing, default 0 **"x" - X position in level. **"xdir" - Horizontal velocity. **"y" - Altitude position in level. **"z" - Z position in level. **"zdir" - Vertical velocity. ==Custom Menu Function== '''loadgamefile()''' * loadgamefile(): reload saved level file from saves (example bor.sav) '''getsaveinfo(set_index, prop)''' * gets the info from *.sav file loaded by loadgamefile(). * if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING). * set_index is the index of your set. from 0 to ... X * prop has these wildcards: **"flag": is there a slot in memory? if yes flag == 1 else 0. **"level" **"stage" **"times_completed" **"score" **"lives" **"credits" **"name" **"playername" **"health" **"mp" getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing. '''playgame(set_index, usesave)''' * set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2. * Example: playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode. '''options()''' * it shows options menu (control, video, etc..) for a custom menu. '''shutdown()''' * it closes the engine. '''gotomainmenu(flag)''' * to go to main menu * flag: gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7 * flag doesn't affect set nogameover/nohof ==Script Compile Functions== '''allocscript(name, comment)''' * it allocs a script in memory. * useful to compile a dynamic script on fly. EXAMPLE: allocscript("Script1", "this script is the 1st one") '''loadscript(handle, path)''' * it loads a script in the handle created by allocscript() from the specified path. EXAMPLE: loadscript(script_handle, "data/scripts/script.c") '''compilescript(handle)''' * it compile a script on fly '''executescript(handle)''' * it executes a script. <pre> void handle = allocscript("script1","any_comment"); loadscript(handle,"data/scripts/script.c"); compilescript(handle); executescript(handle); </pre> NOTE: if you want you can create a script file with filestream functions. then you can load and execute your script on fly! ==String Functions== '''strinfirst(string, substring)''' * search the first match in a string. * params are complete string and substring to search in complete string. * it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1; EXAMPLE: strinfirst("HELLO", "LLO") returns LLO strinfirst("HELLO", "HI") returns -1 '''strinlast(string, substring)''' * like strinfirst() but returns the last substring match. * that is the func search in the string from right (not from left) '''strleft(string, index)''' * it returns a substring, the left part of a string from index 0 to INDEX. EXAMPLE: strleft("HELLO", 4) returns "HELL" '''strright(string, index)''' * like strleft() nut it return the right part from INDEX to END_OF_STRING '''strlength(string)''' * it return the string length. EXAMPLE: strlength("HELLO") returns 5 (the string is length 5 characters) '''strwidth(string)''' * it returns the string width in pixels depending by the font. * if the width of the character is 6 pixels and the string is "HELLO" * strwidth("HELLO") will returns 6x5 = 30 (30 pixels) * useful to align a string in the screen specially if you use multi-byte strings. EXAMPLE: strwidth("HELLO"); EXAMPLE of substr() and getchar(): <pre> char getchar(char str, int index) { if ( index >= strlength(str) ) index = strlength(str)-1; else if ( index < 0 ) index = 0; if ( strlength(str) > 0 ) { str = strright(str, index); if ( strlength(str) > 1 ) { index = 1; str = strleft(str, index); } } //else str = ""; return str; } char substr(char str, int start_index, int length) { if ( start_index+length > strlength(str) ) return NULL(); if ( start_index < 0 || strlength(str) <= 0 ) return NULL(); str = strright(str, start_index); str = strleft(str, length); return str; } </pre> ==Terrain Script Function== '''checkhole(x,z,y)''' * it returns 1 if there's hole here, otherwise it returns 0 * y is optional but if you use it, then you can detect an hole just if hole height (default 0) >= y '''checkholeindex(x,z,y)''' * it works like checkhole() but it returns the index of hole in the level, otherwise it returns -1 * y is optional * you can use hole index for get/change levelproperty '''checkwall(x,z,y)''' * it returns the height of wall from 0 (not wall or height 0) to... X height * y is optional but if you use it, then you can detect walls from height y, otherwise with just 2 params (x,z) it uses the default value (y = 100000) '''checkwallindex(x,z,y)''' * it works like checkwall() but it returns the index of wall in the level, otherwise it returns -1 * y is optional * you can use wall index for get/change levelproperty '''checkbasemap(x,z)''' * it returns the base height in X,Z coords. * if there is a hole, it returns -1000 '''checkbasemapindex(x,z)''' * it works like checkbasemap() but it returns the index of basemap in the level, otherwise it returns -1 * you can use basemap index for get/change levelproperty '''checkplatformbelow(x,z,y)''' * it returns the platform handler (entity) in X,Z coords below y height, otherwise it returns NULL() '''checkplatformabove(x,z,y)''' * it returns the platform handler (entity) in X,Z coords above y height, otherwise it returns NULL() '''checkplatformbetween(x,z,y_min,y_max)''' * it returns the platform handler (entity) in X,Z coords and bewteen y_min and y_max, otherwise it returns NULL() '''generatebasemap(map_index,rx,rz,x_size,z_size,min_y,max_y,x_cont)''' * It generates an inclined terrain * map_index: is the index of basemap. the new basemap must have last_index + 1 -> last_index + 1 == openborvariant("numbasempas") * rx: it generates basemap from coord X * rz: it generates basemap from coord Z * x_size: it generates basemap from coord X to x+x_size * z_size: it generates basemap from coord Z to z+z_size * min_y: is the minimum height * max_y: is the maxmimum height * you can invert min_y and max_y too! * x_cont: is an optional parameter. yif you set it you generate a basemap from x to x_cont as you set from min_y,max_y param, but from x_cont to x_size the basemap will have max_y height. Example: generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont); from x_cont to x_size basemap will have the max_y height. you can handle basemap via get/change levelproperty too to create custom basemap. For example generatebasemap() is the hardcoded version of: <pre> void change_basemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) { float x,z; float delta,y,tmp; int dir = 0; changelevelproperty("basemap", map_index, "x", rx); changelevelproperty("basemap", map_index, "xsize", x_size+2); changelevelproperty("basemap", map_index, "z", rz); changelevelproperty("basemap", map_index, "zsize", z_size+2); if (min_y <= max_y) dir = 1; else { dir = 0; tmp = min_y; min_y = max_y; max_y = tmp; } delta = (max_y - min_y) / ( (x_size <= 0) ? 1 : (x_size-1) ); for( x = 0; x < x_size; x++) { if ( dir == NULL() || dir > 0 ) { if ( x == x_size-1 ) y = max_y; else y = x*delta + min_y; } else y = max_y - (x*delta); // + min_a if ( x_cont != NULL() ) { if ( dir == NULL() || dir > 0 ) { if ( x+rx >= x_cont ) y = max_y; // connect with the wall more smoothly } else { if ( x+rz <= x_cont ) y = max_y; } } for ( z = 0; z < z_size; z++) { changelevelproperty("basemap", map_index, "map", x, z, y); } } } </pre> ==Sound Functions== '''playmusic(name, loop, offset)''' * Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present. * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''fademusic(fade, name, loop, offset)''' * With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music. * fade volume (0 ~ 128) * name: pathname * loop: toggle 1 or 0. 1 for loop music * offset: start music offset '''setmusicvolume(left, right)''' * left: stereo left volume (0 ~ 128) * right: stereo left volume (0 ~ 128) '''setmusictempo(ratio)''' * {ratio} is tempo. Normal ratio is 100. Higher the value, higher the tempo and vice versa. '''pausemusic(toggle)''' * toggle: 1 or 0. 1 to pause music '''pausesamples(toggle)''' * it works like pausemusic() but it works for ALL sounds. '''pausesample(toggle,channel)''' * it works like pausemusic() but it works for one sound at channel #. '''isactivesample(int channel)''' * it returns 1 if channel is active (sound in play), else it returns 0 '''sampleid(channel)''' * returns sample id in channel if sample is active, it returns -1 otherwise '''querychannel(sound_id)''' * query a channel to search is a sound is active. it returns the channel where sound_id is active. '''playsample(id, priority, lvolume, rvolume, speed, loop)''' * id: loaded sample * priority: to play channels with lowest current priority first. default -1 * lvolume: left volume * rvolume: right volume * speed: sound speed (integer): from 0 to.. x * loop: 1 or 0. 1 for loop sound '''loadsample(filename, log)''' * filename: filename to load * log: if 1 it writes a log '''unloadsample(id)''' * id: loaded sample NOTE: to get last sound played use openborvariant("sample_play_id") and to get the max number of channels use: openborvariant("maxsoundchannels") Example of query function use: <pre> int stop_last_sound(int snd_id) { int playid = openborvariant("sample_play_id"); int channel; if ( snd_id != NULL() ) playid = snd_id; //if(playsample(yousampleid)) setentityvar(self, "lastchannel", openborvariant("sample_play_id")); if ( playid ) { channel = querychannel(playid); //drawstring(20,50,0,channel); if ( channel >= 0 ) stopchannel(channel); } return playid; } </pre> ---- =Troubleshooting= ==NONFATAL==: If your mod isn't crashing, but it's still acting funny, check this list: Q: After downloading a new version of OpenBoR, my HUD (life bar, time, etc.) appear at the bottom of the screen and my options and controls are messed up! * Sometimes, the format of the file SETTINGS.SAV will be changed. When this happens, you'll need to delete the SETTINGS.SAV file you currently have in the same folder as OpenBoR and re-open OpenBoR. Q: My entities are a discolored box/have the wrong colors! * OpenBoR uses a pallete system. Make sure the entities have the correct pallete. Q: My entities have tried to attack but nothing happens! * Are you sure you have given attackboxes in their attack animation? Q: I'm using latest version of OpenBoR but something doesn't work like before! * You probably found a bug or something has been changed in the engine. * In either case, report that to LavaLit.com <http://www.lavalit.com/> * Before reporting, double check your find to ensure that it's true. Also please give details for your report. ==FATAL==: If your mod is crashing, OpenBoR will store a little error message in "OpenBoRlog.txt" inside the Logs folder. That's for the Windows version, in DOS the log file is "OpenBoRl.txt". The last line is the error message. Q: Unable to open file '{path}' * Check the path, is the path typed correctly? If it is look for the file, is it placed in right folder or not? * Something is wrong with the file at {path}. Some possible known causes: * One of the file or folder names in the path is too long. OpenBoR can read from files and folders whose names are longer than 8 letters (excluding the extension) but the old packer can't compile those files or folders. To solve this either shorten file/folder name or download newest packer from www.lavalit.com. * Another possible reason is the file is corrupted. Try remaking the file. Q: Failed to create colourmap from images '{path1}' and '{path2}'. * The game tried to make an alternate pallete (remap) of {path1} using the data in {path2}, but couldn't. Some possible known causes: * {path1} and/or {path2} do not exist. They may actually exist and just have the wrong name, so check your spelling if the files are there. * {path1} and {path2} are not based on the same image. They should be the exact same pictures EXCEPT that certain colors in one file have been replaced with another. Q: Command '{com}' not understood in file '{path}' * The line {com} is somewhere in {path}. However, OpenBoR does not have any code for handling {com}, and doesn't know what to do. * Check {com}'s spelling. For instance, it's colourselect, not colorselect. * Make sure you have the latest version of OpenBoR. New features won't work in older versions. Q: Unable to load file '' (may be out of memory) * This is a real sneaky error. It means that one of your .txt files which was just loaded doesn't end with a blank line. * To fix this, just go to the last line in the offending .txt file(s) and press enter once. * This will only crash OpenBoR when the problem file is actually loaded, not when it is 'known' while loading files at the start. Q: DOS/32A warning (9003): real mode interrupt vector had been modified: INT 43h * Roel (creator of the original BoR) finally found out some more about this. It's a Windows/DOS video mode emulation thing. Don't worry about it. It won't damage anything. We think. ---- =Other Stuff= '''Outside the Box:''' * OpenBoR adds a lot to an already powerful, simple engine. But you can take things even further with a little thought. * Just because they're called SHOCK, FREEZE and BURN doesn't mean they need to be bolts, icicles and flares. They could be other elements, or not even elements at all- ever noticed that most fighting games have separate graphics for low, mid, and high-level attacks? Or ever wanted a character to just sit still for a second or two? Among other things... * Related to above, various attackboxes, SHOCK and BURN can be used to make custom slams and custom throws. There are many commands that also helps making them. * Text objects pause the game and can play an animation. You can use it for cutscenes which don't end the level. - Use them wisely as they have to be stored in RAM, while cutscenes are streamed in real-time. * Enemies can drop other enemies. That means you can create enemies with second forms. * An entity's offset, bbox, attack box, platform box, etc. don't need to overlap. Or even be close to one another. '''Cutscenes:''' * There is a difference in the format for animated .gif files and not-animated .gif files. In other words, if you have a single-frame animated .gif, it would be read by OpenBoR differently than an identical non-animated .gif. * These scenes must have animated .gifs: **** data/scenes/logo.txt **** data/scenes/gameover.txt * These scenes must have non-animated .gifs: **** data/scenes/title.txt **** data/scenes/titleb.txt '''Score:''' * When you hit an enemy, you get 5x the attack's damage in points. * THROWing an enemy will earn you the attack's damage in points (you don't get any multipliers). * You get 5x the attack's power in the player's .txt file, not the damage dealt. So an attack with 1000 power would always give 5000 points. * You get a one-up every 50,000 points. '''Time:''' * Try to keep in mind how long it might take a player to beat a group of enemies or a boss. It feels kind of dissapointing to last 99 seconds against a high-health boss or endless stream of enemies, only to die from time over. * To create an item which recovers a player's time, name it Time in it's .txt file and in MODELS.txt and give it a 'health' and 'score' value of 0. '''Projectiles:''' * Knives fly straight forward. They can fly over pits unless they are on the ground. * Stars can only be thrown during jumps. Three fly out at downward angles. * Bombs fly in an arc. They can be thrown over pits. '''Player Swapping:''' * 'load'ing a player character in a level's .txt file will cause the player's character to become the loaded character. You can't bring the character select screen back up, though. * You can allow players to "unlock" characters in-game by only "know"ing the player in MODELS.txt, but putting an item which "load"s the entity in it's header. If a player grabs the item, they will be able to select the new character whenever they run out of lives or go to the select screen. This isn't saved when you close the game, though. '''Other notes:''' * Both OpenBoR.exe and WAV2BOR.exe only work with short file names. If you put them in directories with a file or folder name longer than 8 characters, they won't work. '''Fun:''' * Try to keep your mod interesting. The original BoR engine had a lot of neat tricks and fun potential which was never realized, and OpenBoR increases those possibilities exponentially. Think carefully about what you do with them. * The little things make a difference. The secret enemy in the original BoR's elevator, the wacky names, the entire hidden stage... * There are more fighting styles than just the standard Hadoken fireball/uppercut/spin kick. Try different attacks out. There are some interesting styles and attacks out there. Variety is the spice of life, right? * It's possible to make 2D levels like ones in Mario Bros. If you set 'zmin' and 'zmax' (see above) the same, levels will turn to 2D. '''Limits :''' Maximum number of: * Individual Sprites: NA** * Animations: NA** * Total Frames: NA** * Frames per animation: NA** * Models: NA** * Entities in play: NA** * Panels: 52 (26) - This is the number of individual panels that may be used in a single level. Although the actual limit is 52, you may only use 26 as panels are ordered by letter and no method has been set to move beyond this number. * Panel Use: 100 - This is the number of panel definitions you may use in a single level. * Weapons: NA** (31)- The actual number of weapon models is NA**, but the weapon list in a single model text is limited to 31 items. Switching models directly via script can bypass this limitation for an infinite number of alternates. * Remaps: 30 - Total number of color maps (including the default) available for each model. * Name length: 40 - Number of characters you may use for each entity's name. Remember spaces also count as characters. * Level Spawns: 600 - Maximum number of spawns in each level.txt. Projectiles, scripted spawns, and use of the spawnframe/summonframe commands do not count toward this limit. * Hole: 40 - Number of uses you have for the Hole command per level. * Levels: 100 * Difficulty levels: 10 * Sound effects: 512 * Freespecials: 8 (NA**) - The default limit is 8, but you may redefine number of available freespecials using the Maxfreespecials command. Note that each use of cancel also counts toward the limit of freespecials. * Rush Count: 65,535 - Highest value displayable by the Rush Count (combo meter). * Health: 2,147,483,647 - Maximum possible health for a single entity. * MP: 2,147,483,647 - Maximum possible mp for a single entity. - NA means this particular caveat is no longer limited by source code. In other words, if you want to create a mod with 10,000 models, 5000 animations or an animation with 500,000 frames, that's your business. Keep in mind however that with great power comes great responsibility; it is up to you to properly manage hardware resources (in particular memory), especially if you intend for your module to play on consoles. ---- =FAQ= Q: What do you mean by "entity?" * It's anything you load in Models.txt. It's basically a .txt file which tells the game how to display and use a player, an enemy, a barrel, an apple, etc... Q: What's a "hud?" * HUD: Heads-Up Display. It's what shows you life, your score, your player, etc. It's a display which gives you a heads-up as to what's going on. Q: Can I enter my initials on the high score screen? * Nope, sorry. Q: What is this 'z' which oftenly mentioned in this manual? * That 'z' refers to Z axis, another axis perpendicular to X axis. That's the convention to define 'back' or 'front'. Q: Why don't you use 'y' instead? * That's because 'y' refers to altitude axis instead. Q: I can't find any info about scripting in OpenBoR here! Where is it? * I am really sorry about that. Scripts are more complex than usual commands listed above and they require more explanation. Also scripting basics are required for using scripts. Q: Help! My settings are all wrong/My controls have randomly changed/My high scores were replaced by gibberish! * The settings file format may have changed. Try deleting or moving your settings.sav file in the same directory as OpenBoR and reopening OpenBoR. Q: My settings won't save on the Dreamcast version! * This is a known issue. It seems the Dreamcast VMU (which is the only way to save on the DC) doesn't get along very well with OpenBoR, and getting them to work together would require too many major changes to be possible. Q: Where is the DC/PS2/PSP/Windows/X-Box/Linux/GP32/GP2X/NDS version of OpenBoR? * Windows, DOS, Dreamcast, PSP, GP2X and X-Box binaries/executables are vailable in in the recent releases by SumolX. The PS2 and GP32 ports of the original BoR were all done by separate coders, none of whom have expressed interest in porting OpenBoR. Without skilled coders for those platforms, those ports will not be possible. As of this time, I don't think the NDS version by [[GPF]] is done yet. Q: What is this BoR/OpenBoR/DarkBoR/BoRHed/HoR/AotB thing I keep hearing about? * BoR is the original Beats of Rage. It is a free game made by Senile Team [http://www.senile-team.com/]. It doesn't have most of the features found in OpenBoR, but it is the original. * OpenBoR was an upgraded version of BoR which has been worked on by many coders. DarkBoR was an alternate version of BoR which has several unique features such as an MP bar and enhanced weapons support. It was developed by Tails, but it is now merged with OpenBoR to make a single engine. * BoRHed is an edit of BoR with new features similar to OpenBoR. It is developed by Lord_Ball and hopefully will be merged soon with OpenBoR. * HoR is an edit of BoR designed to create shooting games. It is developed by Lord_Ball. * [[Age of the Beast]] (AotB) is a "sequel" of sorts to the original BoR. The storyline, characters and music are original work made from scratch, but some basic gameplay elements will be similar to the original BoR. It's being developed by Senile Team, creators of the original BoR. Q: Which version of BoR should I use? * OpenBoR is by far the best choice as of this moment. Each version has its advantage though: * The original BoR is the only version with certain ports (such as PS2 or GP32) so it has the greatest compatability. * OpenBoR has many new features and backwards compatability to the original BoR or DarkBoR. It also is the most optimized version. * BoRHed also adds new features, but an entirely different set. * HoR was designed for overhead/sideview shooters, so that's something of a different situation. * [[Age of the Beast]] isn't out yet. So, um, it's not really a choice at the moment. You may be able to create multiple versions compatabile with the different versions of BoR, like how game companies release cross-platform games. That's extra work, though. Q: I'm amazed to see 10 different attackboxes. Why would someone need that many? * You should be amazed on the effects you could make with them. With many attackboxes, modders can make an attack that push an opponent backwards, pull him/her, launchers and other cool effects. Q: When is Age of the Beast going to be released? * When it's done. Coding games is actually a difficult and annoying not-tons-of-fun task. Especially when you don't get paid. And even more so if people ask for demo versions or release dates. It's being worked on. It'll come when it's ready. Asking will at best do nothing and more often just slow things down. Q: I found an error in this guide. * Then please report it at LavaLit.com [http://www.lavalit.com/index.php?topic=45]. Q: I found an error in OpenBoR. * Report bugs at the OpenBoR Sourceforge site to allow to track them easier. http://sourceforge.net/projects/openbor/ (==Select Tracker[=*=]Bugs==) * Use the system in the following manner: **9 - Highest = System Crash / Fatal bug **5 - Medium = Something is just not working correctly and effects the engine in a strange way. **1 - Lowest = cosmetics, small things. * Lastly, Always upload a log file and enter each bug with your username and website (borgeneration/senileteam) and a where/how to be contacted if I don't know you personally. Q: I want something added to OpenBoR. * If you do want to ask for new features, think first. How many people besides you would use the feature? Would it be possible to program? Would it make problems with older versions? Has someone else asked for something similar? If you still want to ask, be sure to do so nicely. The people in the BoR scene are nice, and they are not getting paid for this, so they deserve some little thanks, right? * Also try making them with scripts. If they are doable with scripts, your request for them will be rejected. Q: I want to HELP add something to OpenBoR. * Awesome! Head to LavaLit forums and let SamuraiX know. As a warning, even if your addition is really good, it may not be added. Backwards compatability, speed, memory, and Dreamcast/PSP compatability are all important factors in what gets added or not. Q: Can I make my own version of BoR/OpenBoR/DarkBoR? * Of course. If you're only making small, mod-specific changes (like changing the design of system menus), go ahead. If you're making larger changes (like new features or options), it would be nice if you mentioned it on the OpenBoR forums, but that's still not enforced or anything. Q: How do I make my own version of BoR/OpenBoR/DarkBoR? * Information on how to compile the code for PC, PSP, Dreamcast, GP2X and other platforms can be found at LavaLit.com [http://www.lavalit.com/index.php?board=21.0]. ---- Links * http://www.chronocrash.com/ (Official OpenBOR website) * http://www.senileteam.com/ (Official BoR/Senile Team website) * http://www.lavalit.com/ (LavaLit website) * http://www.irfanview.us/ (Free .gif batch converter) ---- =Credits= ==Beats of Rage== Senile Team: *Original Beats of Rage game. Roel (Opla): *Original BoR source code and engine, major improvements in OpenBoR code, some original BoR graphics. Neill Corlett: *Dreamcast [http://www.dreamcast-scene.com/index.php/Main/Dreamcast] and PS2 Port. ==OpenBoR== L@Cible: *His BoR-DC-Toolchain made OpenBoR possible. Kirby2000: *OpenBoR Maintainer 2004-2005, 4 player support. CGRemakes: *OpenBoR Maintainer 2005-2006. SumolX: *OpenBoR Maintainer 2006-2007, PSP port. uTunnels: *OpenBoR Coder Tails: *DarkBoR, 4 player support. Lord_Ball: *BoRHed, HoR. Drikobruschi: *Contributed hi-score table code. Kbandressen: *OpenBoR Coder Orochi_X: *OpenBoR Coder White Dragon: *OpenBoR Coder Fugue: *Contributed many features, original author of this manual. O Ilusionista: * Current Manual updater. ''OpenBoR Manual contributions'': Bloodbane, bWWd, Zamuel, Christuserloeser, Damon Caskey, White Dragon. ''Sega'': *Original Streets of Rage design, concept, etc. ''SNK'': *Original BoR graphics. ''Sega, Capcom, SNK, Konami, Tecmo, Treasure, Sammy, etc.'': **For all the brawler games! ''The entire BoR and OpenBoR community'': **Keep making those games! 24ce72c39d41e180a8f5db7db7dac6e5d387a4c5 File:Rust-dc-logo.png 6 1432 3407 2024-02-08T21:57:46Z Darc 1 Uploaded own work with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Ferris holding his Dreamcast controller}} |date=2024-02-08 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} 58c193607cee251bb3a64fa5c757fe8d60cac5cf Maple bus 0 113 3411 3368 2024-02-10T02:11:12Z Tails86 160 wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements both Controller and either Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan the entire screen. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 33.36 milliseconds. Assuming a composite signal actually scans 525 lines and horizontal retrace takes 10 microseconds per line, the time window for each pixel on a 60 Hz screen is about 83.6 nanoseconds. If beam detection only occurs in the last 16.68 milliseconds, the shot won't count, and the Dreamcast may also flag the light gun as faulty. If no beam is detected, meaning SDCKB remains HIGH throughout the entire period, then the game normally treats this as a gun reload event. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> 07684573ebbd70bd72b18b411b606844f33e1b37 Gccrs 0 1433 3427 2024-02-17T21:27:19Z Darc 1 Created page with "'''gccrs''' is the Rust compiler frontend for GCC, currently under active development. This Rust compiler is a new implementation of Rust from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust sta..." wikitext text/x-wiki '''gccrs''' is the Rust compiler frontend for GCC, currently under active development. This Rust compiler is a new implementation of Rust from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. It is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. Make sure your shell is currently in the correct directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 6365077a794028c2ddefed3e72a79be49b787bac 3428 3427 2024-02-17T21:27:47Z Darc 1 wikitext text/x-wiki '''gccrs''' is the Rust compiler frontend for GCC, currently under active development. This Rust compiler is a new implementation of Rust from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. Although it is in early stages and highly experimental for Dreamcast dev purposes, it is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. Make sure your shell is currently in the correct directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. 783c6212006269487fce502971648cb83f521433 3442 3428 2024-02-18T00:23:13Z Darc 1 wikitext text/x-wiki '''gccrs''' is the Rust compiler frontend for GCC, currently under active development. This Rust compiler is a new implementation of Rust from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. Although it is in early stages and highly experimental for Dreamcast dev purposes, it is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. Make sure your shell is currently in the correct directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. ==Example project== The [https://github.com/darcagn/rust-fortran-cube/ <code>rust-fortran-cube</code>] repository contains an example project using gccrs in conjunction with GFortran, KallistiOS, and GLdc. View [https://www.youtube.com/watch?v=VUiRoEcpvtI footage of the example] running. This example was created by Eric Fradella and used as a demo in the FOSDEM 2024 talk [https://fosdem.org/2024/schedule/event/fosdem-2024-2634-sega-dreamcast-homebrew-with-gcc/ Sega Dreamcast Homebrew with GCC] by [[User:GyroVorbis|Falco Girgis]]. f26783b509edd53256dcca15417f88df2c2c3f45 3443 3442 2024-02-18T00:28:18Z Darc 1 wikitext text/x-wiki '''gccrs''' is the Rust compiler frontend for GCC, currently under active development. This Rust compiler is a new implementation of Rust from the ground up using the GCC toolchain infrastructure. This project is in early stages and is targeting the Rust 1.49 revision from December 2020. As of this writing (February 2024), it is not yet able to compile Rust's <code>libcore</code>, so many basic language features are unimplemented or not functional. Additionally, Rust standard tooling like <code>cargo</code> is not available. Borrow checking is not implemented, but the project plans to later use the next-generation Rust borrow checker [https://github.com/rust-lang/polonius Polonius] from the official Rust project. At this time, it is recommended to use [[Rust on Dreamcast|'''rustc_codegen_gcc''']] to develop for Dreamcast using Rust instead of gccrs. Although it is in early stages and highly experimental for Dreamcast dev purposes, it is possible to use this compiler by building the GCC 14.0.1-dev toolchain or the '''gccrs''' latest toolchain. GCC 14.0.1-dev will get you the latest code upstreamed by the '''gccrs''' team into the main development branch of GCC, while the '''gccrs''' git repo will get you the absolute latest bleeding edge updates to '''gccrs'''. The GCC 14.0.1-dev configuration file is available within the official KallistiOS repo's <code>dc-chain</code> script, while the latest '''gccrs''' configuration is available within the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository. Brief instructions follow for setting up the latest '''gccrs''' toolchain. See [[Getting Started with Dreamcast development]] for more detailed information on how to set up and run <code>dc-chain</code>. ==Building a gccrs-enabled toolchain== Follow the [[Getting Started with Dreamcast development]] guide for creating a Dreamcast toolchain until you arrive at the instructions for setting up the <code>dc-chain</code> configuration file. Make sure your shell is currently in the correct directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clone the [https://github.com/darcagn/rust-for-dreamcast Rust for Dreamcast] repository: git clone https://github.com/darcagn/rust-for-dreamcast.git rust Copy the GCC patch in place: cp rust/toolchain/gcc-rs-kos.diff patches/ Copy the <code>dc-chain</code> configuration file into place: cp rust/toolchain/config.mk.gccrs.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation). Note that to avoid conflicting with an existing stable toolchain at the default path (i.e. <code>/opt/toolchains/dc/sh-elf</code>), we will be installing to <code>/opt/toolchains/dc/gccrs/sh-elf</code> instead. To begin compilation and installation, run: make build-sh4 After building everything, you can clean up the extraneous files in your <code>dc-chain</code> directory by entering: make clean ==Setting up Makefiles to compile Rust modules== As mentioned before, <code>cargo</code> is not available to use with '''gccrs''', so for our example, we will place our <code>.rs</code> modules within a typical KallistiOS <code>Makefile</code> project. If we assume the module file is named <code>example.rs</code>, you'll need to add <code>example.rox</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>rox</code> object files: <syntaxhighlight lang="make"> %.rox: %.rs kos-cc -frust-incomplete-and-experimental-compiler-do-not-use $(CFLAGS) -c $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. In your <code>example.rs</code> file, your <code>main</code> function will need to be declared like so:. <syntaxhighlight lang="rust"> #[no_mangle] pub extern fn main() -> i32 { [...] } </syntaxhighlight> Make sure before you compile your code that you set <code>export KOS_CC_BASE="/opt/toolchains/dc/gccrs/sh-elf"</code> in your KallistiOS <code>environ.sh</code> file or <code>make</code> will not find your '''gccrs''' compiler executable. ==Example project== The [https://github.com/darcagn/rust-fortran-cube/ <code>rust-fortran-cube</code>] repository contains an example project using gccrs in conjunction with GFortran, KallistiOS, and GLdc. View [https://www.youtube.com/watch?v=VUiRoEcpvtI footage of the example] running. This example was created by Eric Fradella and used as a demo in the FOSDEM 2024 talk [https://fosdem.org/2024/schedule/event/fosdem-2024-2634-sega-dreamcast-homebrew-with-gcc/ Sega Dreamcast Homebrew with GCC] by [[User:GyroVorbis|Falco Girgis]]. e5084698f396c4f19eb844ce87f77621a88ae3a5 Rust on Dreamcast 0 1426 3450 3449 2024-02-18T14:11:26Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS and any '''kos-ports''' being used with a <code>make clean</code> and <code>make</code> for the changes to take effect. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. efa9bd52ac3452ded9042b3974e93b7e953ccb4d 3451 3450 2024-02-18T14:14:15Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have some familiarity with KallistiOS. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. daded277abd55716f43fe52e507f84e6eaf9c27f 3452 3451 2024-02-18T14:19:39Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to the configuration (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 753ca27764e1ff4c49dcb764c90886448a6fa627 3453 3452 2024-02-18T14:21:48Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 98e065e05f7585e65eaadc31adaea4a815c4aa75 3454 3453 2024-02-18T14:23:05Z Darc 1 /* Building a cross-compiling libgccjit.so for rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 48408d36a4a39ce9be0f14418bda0c9b6901b592 3455 3454 2024-02-18T14:25:24Z Darc 1 /* Using Rust for Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== * This will follow the <code>cargo-hello</code> example ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 7e176fb15b83a59906f542295147bdc8aad6b040 3457 3455 2024-02-18T15:32:19Z Darc 1 /* Creating a new Rust project with Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the <code>cargo-hello</code> example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust"> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. c8b4153d3a000abcf677bcf6e6ec233b40286432 3458 3457 2024-02-18T15:35:13Z Darc 1 /* Creating a new Rust project with Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust"> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== * This will follow the <code>cargo-cube</code> example ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 4f1bb38ecebfabb5a2f85362b62290ea22aefde2 3459 3458 2024-02-18T16:13:41Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust"> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. In <code>build.rs</code>, it's necessary to specify to <code>cargo-dc</code> that our project needs '''libGL''' and '''libm''' linked: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to convert JPG images to VQ-compressed textures with <code>vqenc</code> (included with KallistiOS) to be included in our project when <code>cargo-dc build</code> is invoked. '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 8301bc8f3bf02b027428cb199329b8acb7b0fef5 3460 3459 2024-02-18T16:33:27Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust"> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. c4f4a3ec3f932a4774809e8554f578b7f8b4c4c2 3461 3460 2024-02-18T16:38:03Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust"> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 631b86bd682686c606402ba8c70ae28eaf3c7e8c 3462 3461 2024-02-18T16:40:41Z Darc 1 /* Creating a new Rust project with Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 58a02770f518e2327abc4b95bfa087b444139586 3463 3462 2024-02-18T16:46:48Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. ==Integrating a Cargo project with a KallistiOS project== We can also build a crate based on '''kos-rs''' and integrate the Rust code with other C code and KOS libraries. An example rotating 3D cube program built using '''kos-rs''' and <code>cargo-dc</code> combined with a <code>Makefile</code>-based KallistiOS project is included with the '''Rust-for-Dreamcast''' repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rust_cube <code>examples/rust_cube</code>]. Type <code>cargo-dc build</code> to build the project, then invoke <code>make</code> to build the KallistiOS project and link the Rust code within it. 0c5e52efb9136839eb57f4e397556a9fa84fef60 3464 3463 2024-02-18T16:49:55Z Darc 1 /* Integrating a Cargo project with a KallistiOS project */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * libc support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. da103aa74cca458d3b425c00df7adb630fbde959 3465 3464 2024-02-18T16:51:01Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. 67a36614632ba5efb24a979e7e5346f4c5b9a442 3466 3465 2024-02-18T16:52:12Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. ==Creating a new project using Cargo== <code>cargo-dc</code> simplifies invoking <code>cargo</code> and creating Dreamcast crates. When using <code>cargo</code> in this setup, we will need to compile our program and all crate code into a static library <code>.a</code> file, and link it with a KallistiOS trampoline function to start the Rust code. Your Rust code will start with the function you specify as <code>rust_main()</code>. Once you <code>cargo-dc build</code> your Dreamcast code into a <code>.a</code> file, use <code>cargo-dc link</code> to automatically link it with this KallistiOS trampoline function and generate an ELF file. Instructions to do this follow. First, let's clone the [https://github.com/darcagn/kos-rs '''kos-rs'''] repo: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs Create a new crate using <code>cargo-dc</code>: cargo-dc new example --lib Change the crate to a static library in <code>Cargo.toml</code> by changing the <code>crate-type</code> as follows: <syntaxhighlight lang="toml"> crate-type = ["staticlib"] </syntaxhighlight> Add the '''kos-rs''' crate to your <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Add the following function to your crate's <code>src/lib.rs</code> file: <syntaxhighlight lang="rust"> #[no_mangle] pub extern "C" fn rust_main(_argc: i32, _argv: *const u8) -> i32 { [...] return 0; } </syntaxhighlight> The <code>rust_main()</code> function will serve as the entry point to your Rust code. An example "Hello, world!" style program built using '''kos-rs''' and <code>cargo-dc</code> is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>examples/cargo-hello</code>]. Type <code>cargo-dc build</code> to build the project, then <code>cargo-dc link</code> to link against KallistiOS and generate a <code>cargo-hello.elf</code>. Make sure you have your KallistiOS <code>environ.sh</code> sourced in your terminal before running the link command. 44adabee4185425f5b6d90f4b84081eb0d81b395 3467 3466 2024-02-18T16:58:05Z Darc 1 /* Creating a new project using Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. 0439b9eff6964252332c613dd2a4e9bffaed8ab8 3468 3467 2024-02-18T16:58:19Z Darc 1 /* Creating a new Rust project with Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library for Dreamcast== * This will follow the <code>cargo-addlib</code> example ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. b6e15345320af76d78c712e78a7dff84b9a9bf90 3469 3468 2024-02-18T17:22:48Z Darc 1 /* Creating a Rust library for Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. a5683ec2df564d2f3e07fc2ef16ba012760f478a 3470 3469 2024-02-18T17:30:03Z Darc 1 /* Creating a Rust library */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. d0cd520d1717b358d345bea31c37b4ef8a9553cf 3471 3470 2024-02-18T17:34:41Z Darc 1 /* Creating a Rust library */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== * This will follow the <code>rustc-hello</code> example To incorporate Rust source files into a standard KallistiOS <code>Makefile</code>-based project, you can use the <code>rustc-dc</code> wrapper. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> Alternatively, you can add those lines to your KallistiOS <code>Makefile.rules</code> file to avoid having to place it in every project's <code>Makefile</code>. An example "Hello, world!" program built in this style which also demonstrates basic C interoperation is included with the Rust-for-Dreamcast repository, located at [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>examples/rustc-hello</code>]. 80e4644da548538cc00c6a9626c2b27b20a9de40 3472 3471 2024-02-18T17:59:36Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using '''rustc_codegen_gcc'''. For more information on using '''gccrs''', see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. e773b05d4cfa5ea58e110225b367cadb37413d64 3474 3472 2024-02-18T22:07:37Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. cd2893e509aa3919c1f5d1e602218933c5ec863a 3475 3474 2024-02-18T22:08:32Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast <code>rust-for-dreamcast</code> repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 72b640697ce8b16137d98bec280d37873a681c1c 3476 3475 2024-02-18T22:15:16Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast <code>rust-for-dreamcast</code> repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. ea5ba1a04a8b007946d94d7c671d71e240c76a9e 3477 3476 2024-02-18T23:15:27Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast <code>rust-for-dreamcast</code> repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 8d1776d5614f2858f213e93ad666f2820b596ee2 3478 3477 2024-02-18T23:52:46Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast <code>rust-for-dreamcast</code> repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up '''rustc_codegen_gcc''' to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, '''rustc_codegen_gcc''' is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use '''rustc_codegen_gcc''', we must compile <code>libgccjit.so</code>, the '''libgccjit''' library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to '''libgccjit'''. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation, you may also need to rebuild libgccjit to pull down changes rustc_codegen_gcc depends upon. We will first clone the <code>rust-for-dreamcast</code> repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the <code>rust-for-dreamcast</code> repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the '''rustc_codegen_gcc''' configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Clone the '''rustc_codegen_gcc''' to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc '''rustc_codegen_gcc''' needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The <code>rust-for-dreamcast</code> repository contains scripts and wrappers to assist you in building '''rustc_codegen_gcc''' and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above lines to your shell's startup file or else you'll need to run them every time you open a new shell. Now we can use the included scripts to set up '''rustc_codegen_gcc'''. Various patches need to be applied to '''rustc_codegen_gcc''' for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build '''rustc_codegen_gcc'''! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * <code>rustc-dc</code> script can be used to compile Rust modules * <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * <code>cargo-hello</code> demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * <code>cargo-cube</code> demonstrates a Rust project using KallistiOS with GLdc * <code>cargo-addlib</code> demonstrates how to create a Rust library that can be included with a KallistiOS project * <code>rustc-hello</code> demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project These examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs ==Creating a new Rust project with Cargo== We'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our '''kos-rs''' crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 2444def899a2037ca2c818afed9c8cdfc7822eed 3479 3478 2024-02-19T00:09:28Z Darc 1 /* Using rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the <code>rust-for-dreamcast</code> repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the '''GLdc''' graphics and '''libm''' math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 285908531eaa913930a953b4fa12bbf5d9cca375 3480 3479 2024-02-19T00:10:52Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the <code>rust-for-dreamcast</code> repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 22214515f2006b8f83ea2480c7eb36cd486f3d02 3481 3480 2024-02-19T00:11:43Z Darc 1 /* Creating a Rust library */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the <code>rust-for-dreamcast</code> repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 1c57dc8d1fbb6e32a340af6648095bcee7966e32 3482 3481 2024-02-19T00:12:45Z Darc 1 /* Compiling individual modules into object files with rustc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. We'll need to add the path to those scripts to our <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. cb7bfa48213d366502f663edc61a6fb85ca2d59e 3483 3482 2024-02-19T00:15:34Z Darc 1 /* Building rustc_codegen_gcc */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hellow cd hellow Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. beed58ac9db4eb4ef85d618f02bd29f9991ab60a 3484 3483 2024-02-19T00:19:56Z Darc 1 /* Creating a new Rust project with Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hellow.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 5c6d1ed6740948650250545b1b3f36081e250b2f 3485 3484 2024-02-19T00:20:42Z Darc 1 /* Creating a new Rust project with Cargo */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 6b9e4636d89a43d3e3210241ba2c5821e2baff9a 3486 3485 2024-02-19T00:22:36Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll edit our <code>build.rs</code> file to add: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. d239c7dc83bd6584aefa9f629816f5f9b5c51a3d 3487 3486 2024-02-19T00:23:42Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because this is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. ab6e20bf0a08c916a3dc8f95ac2a6e5802019c29 3488 3487 2024-02-19T00:24:24Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 8dbe732cd0548414da82c7909465ef6ee07b54d1 3489 3488 2024-02-19T00:24:45Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''WIP''': This article is currently under construction. The repos linked to below are not yet live. '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. bd0243cab3e2226bc33011ada8d590b4bfbcec46 3490 3489 2024-02-19T00:54:56Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. c94101074ce25ca65c2d0e57ecdc24ec11e41742 3492 3490 2024-02-19T01:00:27Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Using rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build ==Using Rust for Dreamcast== If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. cc23dec025f29d5bcc9fae344018f6191a944f08 3493 3492 2024-02-19T01:25:51Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some patches and workarounds to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 5ada7202578b9d0422c64a606d9bd904b54c5d70 3494 3493 2024-02-19T01:48:19Z Darc 1 /* Building rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC Neither solution is complete at this time, and both are under active development. Using either of them to target the Dreamcast should be considered experimental. '''rustc_codegen_gcc''' is quite further along, however, and is quite usable with some patience with its current limitations and rapid change. On the other hand, while '''gccrs''' can compile for Dreamcast, it is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 61c9ecf829b471d51c696eb38e7183b1f4f87e69 3495 3494 2024-02-19T02:03:23Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC While neither solution is complete at this time, '''rustc_codegen_gcc''' is much further along and is quite usable with some patience with its current limitations and rapid change. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 3564879d449f4c2d9fd0627a819f6b2e38083639 3496 3495 2024-02-19T02:04:19Z Darc 1 /* Building rustc_codegen_gcc to develop on Dreamcast */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC While neither solution is complete at this time, '''rustc_codegen_gcc''' is much further along and is quite usable with some patience with its current limitations and rapid change. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing some early basic [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': There is a currently a bug in GLdc when using <code>-m4-single</code>, which is required when using Rust. A [https://gitlab.com/simulant/GLdc/-/merge_requests/114 merge request] has been submitted upstream for the issue. In the mean time, the cube will not appear correctly unless you apply the small changes shown in the merge request and rebuild the GLdc kos-port. To do this, change directory to <code>$KOS_PORTS/libGL</code>, run <code>make uninstall clean</code>, then run <code>make fetch</code> to retrieve fresh sources. Open <code>dist/libGL-1.0.0/GL/matrix.c</code> in your text editor and [https://gitlab.com/simulant/GLdc/-/merge_requests/114/diffs make these changes], then run <code>make install</code> to compile and install the fixed GLdc.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 5beb8b4a1ff0c1540a2a7573ce0e30beaf25aa3d 3498 3496 2024-02-19T12:21:10Z Darc 1 /* Creating a Rust project using kos-ports libraries */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC While neither solution is complete at this time, '''rustc_codegen_gcc''' is much further along and is quite usable with some patience with its current limitations and rapid change. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing some early basic [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Next, we'll need to let Cargo know about our custom link wrapper script. Create a <code>.cargo</code> directory, and within it, a new <code>config</code> file: mkdir .cargo touch .cargo/config Open this new <code>.cargo/config</code> file in your text editor, add the following entry: <syntaxhighlight lang="toml"> [target.sh-elf] linker = "sh-link-wrapper" </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': If you already had GLdc built, make sure you pull the latest GLdc and rebuild with <code>-m4-single</code> -- a very recently fixed bug prevented this demo from working properly under <code>-m4-single</code>.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. 9139af8cbae9e82c86737800e517a1ee5a7269d1 3499 3498 2024-02-20T23:36:23Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC While neither solution is complete at this time, '''rustc_codegen_gcc''' is much further along and is quite usable with some patience with its current limitations and rapid change. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing some early basic [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': If you already had GLdc built, make sure you pull the latest GLdc and rebuild with <code>-m4-single</code> -- a very recently fixed bug prevented this demo from working properly under <code>-m4-single</code>.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. b25a3a75fb501ad9f35a4288a5d2f5657fbf6a22 DCWiki:Software 4 81 3456 3208 2024-02-18T14:28:01Z Darc 1 /* Software */ wikitext text/x-wiki == Software == {| style="width:100%" ! style="width: 50%"|Dreamcast Games and Software ! style="width: 50%"|Development and Technical |- | style="padding: 5px;vertical-align:top"| * Officially [[Licensed games and software|licensed games and software]] * [[Online Services]] * Commercially sold, independently developed [[Indie games|indie games]] * 3rd-party [[Unlicensed software|unlicensed software]] * [[Freeware homebrew games|Homebrew games and ports]] (freeware) * [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast * [[Media players]] * [[Hardware Tests]] * [[Other Dreamcast software]] (utilities and other miscellanea) * [[VMU games]] * [[Old tools]] | style="padding: 5px;vertical-align:top"| {| * [[Development]] ** [[Getting Started with Dreamcast development|Get Started]] ** [[Programming language support]] ** [[Engine & Library]] ** [[Tools and Utilities]] ** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation] * [[VMU development]] * [[Dreamcast emulators]] * [[VMU emulators]] * [[Boot process]] * [[Memory map]], [[VRAM]] * [[IP.BIN]], [[MR image]], [[Scrambling]] * [[BIOS]] * [[Useful programming tips]] * [[NetBSD/Dreamcast]] |} |} 8ccab34babf833584971a01e02933c121f808dc7 Getting Started with Dreamcast development 0 694 3473 3357 2024-02-18T21:19:57Z Darc 1 /* Burning an example program to CD-R */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and Objective-C++ on Dreamcast (with D and Rust support coming soon) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Further= At this point, you will have a cross-compiler built so that you can generate programs for your Dreamcast from code. KallistiOS, the Dreamcast development library and operating system, is built, as is its associated packages within kos-ports, and all of its example programs. At this point, you will likely want to view some of the following articles: * Setting up an IDE for Dreamcast development ** [[Qt Creator Dreamcast Development Environment]] ** [[CLion Debugging]] ** [[Visual Studio Code]] * [[Creating a first project with KallistiOS]] ('''TODO''': Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it) * [[Using a debug link]] * [[Burning an example to CD-R]] =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Dependencies required: * Homebrew: <code>meson libisofs</code> * Debian/Ubuntu: <code>libisofs-dev meson ninja-build</code> * Fedora: <code>meson ninja-build</code> * Arch: <code>meson</code> Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) 9f06e90fb8bfa0a2d4347013a16a07882dd29e12 3497 3473 2024-02-19T02:48:51Z Darc 1 /* Introduction */ wikitext text/x-wiki <div style="float:right;">__TOC__</div> =Introduction= This article will cover the entire beginning process: starting from zero to having a working dev environment with debug link (serial or IP) and self-booting CD-R. This guide will cover the process for the following platforms: * '''Microsoft Windows 10''' via [https://learn.microsoft.com/en-us/windows/wsl/about Windows Subsystem for Linux] ** Users desiring a native Windows approach, see [[DreamSDK]] instead * '''macOS''' on Intel or Apple Silicon systems with the [https://brew.sh/ Homebrew] package manager installed * '''Linux'''-based systems ** '''Debian'''- and '''Ubuntu'''-based distributions using the default '''apt''' package manger ** '''Fedora'''-based distributions using the default '''dnf''' package manager ** '''Arch'''-based distributions using the default '''pacman''' package manager ** '''Alpine'''-based distributions using the default '''apk''' package manager ===Need help?=== Important note: ''This guide aims to remain up to date and work on all of the above platforms, but keeping instructions for such a variety of platforms up-to-date can be difficult. If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ===Terms=== Before we get started, let's define several terms: The '''toolchain''' is a set of programs which turns your code into an executable file for your Dreamcast console. The toolchain includes: * '''GCC''', a compiler which supports C, C++, Objective-C, and more (see also [[Rust on Dreamcast]] and [[Programming language support]]) * '''binutils''', an assembler and linker * '''newlib''', a C library * '''gdb''', a debugger The toolchain includes a compiler for the Dreamcast's main SH4 CPU, and optionally a compiler for the ARM-based AICA sound processor. Your operating system may already have versions of these programs installed to compile code for your computer, but we will need to build a "cross-compiler" for compiling specifically for the Dreamcast. '''KallistiOS''' or ''KOS'' is an open source development library and pseudo-operating system for the Dreamcast console. It is the best documented and most widely used development kit in the homebrew community. KallistiOS's very flexible license allows both homebrew and commercial use with no restrictions other than a requirement to include credit for its use in your project, and indeed almost all commercially sold indie Dreamcast titles use it. There are others in existence, like [[libronin]] and [[libdream]], as well as the older development kits [[Katana]] and [[Windows CE]] created by Sega and Microsoft for use in retail games, but this guide will only cover the setup and use of KallistiOS. '''kos-ports''' is a repository including various libraries which integrate with KallistiOS. We will download and compile these libraries as well. The '''debug link''' is a generic term referring to a hardware accessory to facilitate quickly running and debugging your programs. IP-based links include the Dreamcast's '''[[Broadband adapter]]''' and '''[[LAN adapter]]''' accessories, and serial-based links include the [[Coder's cable]], which is a cable that can connect the Dreamcast's serial port to your computer via USB or serial. This guide includes instructions for setting up and using the the Broadband adapter and a USB-based coder's cable. '''dc-tool''' and '''dcload''' are a pair of programs to facilitate using a debug link. ''dc-tool'' runs on your computer and links to a Dreamcast running ''dcload-ip'' or ''dcload-serial''. With this setup, you can quickly load programs, read console feedback, load assets, transfer data, redirect I/O, handle exceptions, debug problems, and so forth. =Choosing a debug link solution= If you are building the toolchain for the purpose of building existing programs from source with little to no modifications, then a debug link setup might not be necessary for you. You may simply build programs to burn directly to CD-R. However, if you are planning to actively develop for the Dreamcast, then a debug link is a critical component. While Dreamcast emulators are mature and accurate enough to play the vast majority of the system's games library without issue, many critical bugs may show up on a real Dreamcast system, but not on a Dreamcast emulator. Therefore, it is highly recommended to test on a real system as much as possible. It's also possible to load software off of a [[Serial SD card adapter]], but without an active link to a computer, debugging and stepping through programs as they execute is significantly more challenging. Presented below is a table comparing the different options available for a debug link. Due to the cost, potential buyers may want to factor in the ability to play multiplayer games with their purchase. Thus, for comparison, we have included information about the [[Modem]] with [[DreamPi]] as well, but understand that the Modem with DreamPi cannot be used as a debug link. {| class="wikitable" !colspan="6" |Comparison of various Dreamcast connectivity options |- |style="background-color:#c0c0c0;" width="150" | Device: |style="background-color:#d0d0d0;" width="400" | [[Broadband adapter]] (HIT-400 or HIT-401) <br />Realtek RTL8139C chipset |style="background-color:#d0d0d0;" width="400" | [[LAN adapter]] (HIT-300) <br />Fujitsu MB86967 chipset |style="background-color:#d0d0d0;" width="400" | [[Modem]] with [[DreamPi]] |style="background-color:#d0d0d0;" width="400" | USB [[Coder's cable]] |style="background-color:#d0d0d0;" width="400" | Serial [[Coder's cable]] |- |style="background-color:#d0d0d0;" | Useful for dev? || Yes, supports dcload-ip || Yes, supports dcload-ip,<br/>but BBA is superior and cheaper || No, only useful for online multiplayer gaming || Yes, supports dcload-serial || Yes, supports dcload-serial |- |style="background-color:#d0d0d0;" | Cost || $100 - $200 and up on used markets || $200 and up on used markets,<br/>due to extreme rarity || Kit prices vary, around $100 || See [[Coder's cable]] for vendors<br />darc sells for $45, RetroOnyx sells for $85 || Varies on used markets, uncommonly sold |- |style="background-color:#d0d0d0;" | Can make DIY? || No || No || Yes || Yes || Yes |- |style="background-color:#d0d0d0;" | Performance || Up to 100 megabits/s || Up to 10 megabits/s || Up to 56 kilobits/s || Up to 1500 kilobits/s || Up to 120 kilobits/s |- |style="background-color:#d0d0d0;" | Games support || Some games: Phantasy Star Online, Quake III Arena, Toy Racer, POD SpeedZone, Propellor Arena, Unreal Tournament<br />Some browsers: Broadband Passport, PlanetWeb 3.0 || No games<br />One browser: Dream Passport for LAN || All multiplayer games with network support<br />All web browsers || NO multiplayer games support || NO multiplayer games support |- |style="background-color:#d0d0d0;" | Homebrew support || Homebrew utilities like dcload-ip || Homebrew utilities like dcload-ip || Homebrew utilities don't support, only multiplayer games || Homebrew utilities like dcload-serial || Homebrew utilities like dcload-serial |} =Setting up and compiling the toolchain with the dc-chain script= ===Dependencies=== First, we'll need to install dependencies before building the toolchain. Below we have provided commands to install these dependencies on various systems. Many of the packages will likely already be installed on your system, but we have provided an exhaustive list for good measure. ====macOS 13 Ventura on an Intel or Apple Silicon processor==== First, make sure you install Apple Xcode, including the Command Line tools. You will also need to install several other packages for which we'll include instructions assuming you have installed the [https://brew.sh/ Homebrew] package manager on your system. brew install wget gettext texinfo gmp mpfr libmpc libelf jpeg-turbo libpng meson libisofs ''Important Note for Apple Silicon users'': On Apple Silicon, Homebrew installs libraries to a path not included by default by the compiler. If you haven't added these to your '''~/.zprofile''', then add the following lines now and reload your session (or run them in your Terminal session whenever you compile KOS): export CPATH=/opt/homebrew/include export LIBRARY_PATH=/opt/homebrew/lib ====Debian/Ubuntu-based Linux==== sudo apt-get update sudo apt install gawk patch bzip2 tar make libgmp-dev libmpfr-dev libmpc-dev gettext wget libelf-dev texinfo bison flex sed git build-essential diffutils curl libjpeg-dev libpng-dev python3 pkg-config libisofs-dev meson ninja-build ====Fedora-based Linux==== sudo dnf install gawk patch bzip2 tar make gmp-devel mpfr-devel libmpc-devel gettext wget elfutils-libelf-devel texinfo bison flex sed git diffutils curl libjpeg-turbo-devel libpng-devel gcc-c++ python3 rubygem-rake meson ninja-build ====Arch-based Linux==== sudo pacman -S --needed gawk patch bzip2 tar make gmp mpfr libmpc gettext wget libelf texinfo bison flex sed git diffutils curl libjpeg-turbo libpng python3 meson ====Alpine-based Linux==== sudo apk --update add build-base patch bash texinfo gmp-dev libjpeg-turbo-dev libpng-dev elfutils-dev curl wget python3 git ====Other Linux distributions==== If you're using a different Linux- or Unix-based system besides the one above, you may need to reference your distribution's package database and package manager documentation for the equivalent package names and commands necessary for your system. ===Creating a space for your toolchain installation=== Create the path where we'll install the toolchain and KOS, and grant it the proper permissions: sudo mkdir -p /opt/toolchains/dc sudo chmod -R 755 /opt/toolchains/dc sudo chown -R $(id -u):$(id -g) /opt/toolchains/dc ===Cloning the KOS git repository=== Clone the KOS git repository to your system: git clone https://github.com/KallistiOS/KallistiOS.git /opt/toolchains/dc/kos ===Configuring the dc-chain script=== Enter the dc-chain directory: cd /opt/toolchains/dc/kos/utils/dc-chain We will choose the default '''stable''' configuration for the toolchain, which currently uses GCC 13.2. For advanced users, other configurations are available to you; read the <code>README.md</code> file in the dc-chain directory for more information if you are interested. cp config/config.mk.stable.sample config.mk Now, you may configure config.mk options to your liking by using a text editor. You may alter the <code>makejobs</code> parameter to the number of threads available on your CPU to speed up the compilation, if desired. However, if you run into errors during compilation, you may want to set <code>makejobs=-j1</code>, as on some operating systems the toolchain may fail to build with a higher setting. ===Downloading and compiling the toolchain=== Now we will run a script to download files and compile the toolchain. At this point, we have the option of building both the main CPU SH4 compiler and the AICA sound processor ARM compiler, or we can skip the ARM compiler and just build the SH4 compiler. Thankfully, KallistiOS includes a prebuilt sound driver, so the ARM compiler is only necessary if you're wanting to make changes to the sound driver or write custom code to run on the sound processor. To build '''only the SH4 compiler''': make build-sh4 To build '''both''' the SH4 and the ARM compilers: make This will download and unpack the relevant necessary files and then begin the compilation process. The compilation can take anywhere from minutes to a few hours depending on your CPU and number of threads available. When successfully finished, the toolchains will be ready. Afterwards, if desired, you may also compile the GNU Debugger (gdb) as well: make gdb The GNU Debugger is now installed along with your toolchains. ===Cleaning up temporary files=== After building everything, you can clean up the extraneous files in your dc-chain directory by entering: make clean =Configuring and compiling KOS and kos-ports= ===Setting up the environment settings=== Enter the KOS directory: cd /opt/toolchains/dc/kos Copy the pre-made environment script into place: cp doc/environ.sh.sample environ.sh For most users, the default settings will suffice. However, advanced users may edit the environ.sh to your liking if you'd like to change compile flags or alter paths. If you'd like to have multiple KOS versions installed or multiple toolchain versions installed, you can set up different environ.sh files corresponding to these different configurations by altering the paths. Run the source command on the desired environ.sh file to select that configuration prior to compiling your project. You will need to run the source command to apply the KOS environment settings to your currently running shell. Run the following now, '''and''' ''whenever'' you open a new shell to work on Dreamcast projects: source /opt/toolchains/dc/kos/environ.sh ===Building KOS=== Build KOS: make KOS is now built. ===Building kos-ports=== Clone the kos-ports repository to your system: git clone --recursive https://github.com/KallistiOS/kos-ports /opt/toolchains/dc/kos-ports Run the script to build all of the included ports: /opt/toolchains/dc/kos-ports/utils/build-all.sh kos-ports is now built. ===Building the KOS examples=== Enter the KOS examples directory: cd /opt/toolchains/dc/kos/examples/dreamcast Build the examples: make All of the example programs provided with KallistiOS are now built. =Further= At this point, you will have a cross-compiler built so that you can generate programs for your Dreamcast from code. KallistiOS, the Dreamcast development library and operating system, is built, as is its associated packages within kos-ports, and all of its example programs. At this point, you will likely want to view some of the following articles: * Setting up an IDE for Dreamcast development ** [[Qt Creator Dreamcast Development Environment]] ** [[CLion Debugging]] ** [[Visual Studio Code]] * [[Creating a first project with KallistiOS]] ('''TODO''': Explain how to create a new DC project folder with Makefile, adding an external library, create a basic program, and compile it) * [[Using a debug link]] * [[Burning an example to CD-R]] =Running an example program through a debug link= '''TODO''': ''Give a tutorial on compiling dcload/dc-tool, setting up a serial, USB, or IP debug link, and running 2ndmix demo on real hardware.'' Download and burn the [[:File:Dcload-2023-06-22.zip|latest versions of dcload-ip or dcload-serial]] -- the IP version includes improved DHCP support, so there is no longer a need to configure things beforehand. Run one of the examples from the <code>kos/examples/dreamcast</code> directory with one of the following commands: dc-tool-ip -t <dreamcast IP address> -x example.elf dc-tool-ser -t <serial device path> -x example.elf Run <code>dc-tool-ip</code> or <code>dc-tool-ser</code> without any parameters to get additional options. =Burning an example program to CD-R= '''TODO''': ''Explain how to build mkdcdisc and write 2ndmix demo to CD-R and run on a Dreamcast console'' [https://gitlab.com/simulant/mkdcdisc mkdcdisc] can be used to easily generate a burnable self-boot CDI image. Dependencies required: * Homebrew: <code>meson libisofs</code> * Debian/Ubuntu: <code>libisofs-dev meson ninja-build</code> * Fedora: <code>meson ninja-build</code> * Arch: <code>meson</code> Build <code>mkdcdisc</code>: git clone https://gitlab.com/simulant/mkdcdisc.git cd mkdcdisc meson setup builddir meson compile -C builddir ./builddir/mkdcdisc -h and create a CDI image from your compiled ELF like so: mkdcdisc -e MyProgram.elf -o MyProgram.cdi Then you can burn the CDI file using DiscJuggler (Windows-only, but also works through [https://www.winehq.org/ WINE]), ImgBurn with the CDI plugin, or the cdiburn *nix script floating around out there. (document this better) 33b78355706a86669d8c15027c9a21ead1e03a2c File:Rust-Cube rustc codegen-gcc demo.gif 6 1434 3491 2024-02-19T00:59:39Z Darc 1 Uploaded own work with UploadWizard wikitext text/x-wiki =={{int:filedesc}}== {{Information |description={{no|1=Rust-Cube rustc_codegen-gcc demo}} |date=2024-02-18 |source={{own}} |author=[[User:Darc|Darc]] |permission= |other versions= }} =={{int:license-header}}== {{licensing|generic}} d9b17976b95ac3c533b69e5a6a0b15b07c7e2412 Rust on Dreamcast 0 1426 3500 3499 2024-02-20T23:49:13Z Darc 1 wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC While neither solution is complete at this time, '''rustc_codegen_gcc''' is much further along and is quite usable with some patience with its current limitations and rapid change. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing some early basic [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation, either using your operating system's package manager or [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': If you already had GLdc built, make sure you pull the latest GLdc and rebuild with <code>-m4-single</code> -- a very recently fixed bug prevented this demo from working properly under <code>-m4-single</code>.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. ==Adjusting build settings== Build settings can be adjusted through the <code>CG_GCCFLAGS</code> and <code>CG_RUSTFLAGS</code> environment variables. For example, invoking cargo like so: CG_GCCFLAGS="-freorder-blocks-algorithm=simple" cargo-dc build will build the project while passing along the <code>-freorder-blocks-algorithm=simple</code> optimization setting to the GCC backend. <code>rustc-dc</code> will also pass through these settings. If you wish to adjust the default flags passed to GCC, they are specified in the <code>common.sh</code> file. If you wish to have <code>cargo-dc</code> pass through <code>RUSTFLAGS</code> arguments to the <code>rustc</code> compiler frontend, you can do so by using the <code>CG_RUSTFLAGS</code> environment variable. fd724073f7a38f45469e59bdd580282cc10f9bf4 3502 3500 2024-03-06T18:27:12Z Darc 1 /* Prerequisites */ wikitext text/x-wiki [[File:Rust-dc-logo.png|thumb|Ferris holding his Dreamcast controller]] '''Rust''' is a systems programming language rising in popularity which emphasizes memory safety and performance. Due to its operating at a low level, it is an ideal candidate for running on the Dreamcast. Doing so presents a bit of a challenge, however, as the official Rust compiler is based on the [https://llvm.org/ LLVM] toolchain infrastructure, which does not support the Dreamcast CPU's SuperH architecture. Dreamcast programming is instead typically done with [https://gcc.gnu.org/ GCC], the GNU Compiler Collection. There are currently two viable solutions to this challenge: * '''rustc_codegen_gcc''': A libgccjit-based codegen backend for rustc (preferred method) * '''gccrs''': a Rust frontend for GCC While neither solution is complete at this time, '''rustc_codegen_gcc''' is much further along and is quite usable with some patience with its current limitations and rapid change. On the other hand, '''gccrs''' can compile for Dreamcast, but is in a very early stage, with much of the language unimplemented and no '''libcore''' support. Below we will focus on using rustc_codegen_gcc. For more information on using gccrs, see the [[gccrs]] page. =Building rustc_codegen_gcc to develop on Dreamcast= With [https://github.com/rust-lang/rustc_codegen_gcc rustc_codegen_gcc], we can interface the standard '''rustc''' compiler frontend with '''libgccjit''', a GCC code-generation API. With the help of the [https://github.com/darcagn/rust-for-dreamcast '''Rust-for-Dreamcast''' repo] and the [https://github.com/darcagn/kos-rs '''kos-rs''' crate] containing some early basic [[KallistiOS]] bindings, we can set up rustc_codegen_gcc to compile Rust programs with [https://doc.rust-lang.org/core/ '''core'''] and [https://doc.rust-lang.org/alloc/ '''alloc'''] support (but not the entirety of [https://doc.rust-lang.org/std/ '''std''']). Rust-for-Dreamcast includes wrapper scripts to invoke the rustc and '''cargo''' tools in a familiar way. The familiar borrow checker still works, and one can import and use <code>no_std</code> crates. Despite this support, rustc_codegen_gcc is still in active development, so if using such a setup, expect that things may change rapidly over time. We will need to use some provided patches and scripts to make this solution work. See the rustc_codegen_gcc [https://blog.antoyo.xyz/ progress reports] for more information on the upstream project's progress. '''What Works''' * '''libcore''' -- the core components of the language for running on bare metal (basics like integers, floats, enums, bools, chars, tuples, arrays, slices, closures, iterators, etc.) * '''liballoc''' -- the core components of the language that require a heap, including collections (Vec, String, Box, etc.) * linking to KallistiOS -- KallistiOS and kos-ports can be used if one manually manages interoperating with C via '''unsafe''' * including <code>no_std</code> crates with the <code>cargo</code> build system '''Future Goals''' * '''libc''' support -- Adding KallistiOS support to Rust's libc crate * '''libstd''' support -- built-in language support for I/O, networking, threads, time and date, HashMap/HashSet, unwinding on panic, etc. * KallistiOS bindings -- properly idiomatic Rust support for KallistiOS * Inclusion as a tier 3 target officially * Expansion of <code>cargo-dc</code> to support more dcdev-specific functionallity like generating Dreamcast disc images using metadata specified in <code>Cargo.toml</code> ==Prerequisites== We will build rustc_codegen_gcc support for the Dreamcast in the instructions below. Before we begin, though: * You must already have a KallistiOS development environment set up. This means you have installed the typical dependencies, you have created a cross-compiling toolchain for SH4, you have set up your KallistiOS <code>environ.sh</code> file, and you have built KallistiOS with it. Ideally, you will already have at least some familiarity with KallistiOS dev already. See [[Getting Started with Dreamcast development]] for more information, as well as the [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen]. ** For the purposes of this guide, we will assume you are using the standard paths for Dreamcast development tools; i.e. your environment is set up in <code>/opt/toolchains/dc</code>. Some included scripts and examples may assume this. ** Your KallistiOS installation will need its <code>KOS_SH4_PRECISION</code> setting set to <code>-m4-single</code>. At this time, rustc_codegen_gcc support will not compile with KallistiOS's default <code>-m4-single-only</code> setting. This setting can be changed in KallistiOS's <code>environ.sh</code>, but changing the setting may require you to rebuild your toolchain if you have not built it with <code>m4-single</code> support (which is off by default, but can be enabled in the <code>config.mk</code> file). Once you modify the setting in your <code>environ.sh</code> and re-source the <code>environ.sh</code>, you'll need to rebuild KallistiOS with a <code>make clean</code> and <code>make</code> for the changes to take effect. '''kos-ports''' being used will also need rebuilding with <code>-m4-single</code>. Keep in mind, however, that because KallistiOS doesn't officially support <code>-m4-single</code> yet, some things may be broken, especially libraries in kos-ports that haven't been heavily tested with this setting. * You must already have a relatively up-to-date Rust installation using [https://rustup.rs/ rustup]. Ideally, you will already have some familiarity with Rust's tools. * Install the <code>jq</code> and <code>xxd</code> packages for your operating system. <code>xxd</code> might be part of <code>vim</code> depending on the organization of your operating system's package manager. ''If you run into any errors or other challenges while following this tutorial, or simply need clarification on any of the steps, feel free to ask for assistance on the [https://dcemulation.org/phpBB/viewforum.php?f=29 message board] and we would be happy to aid you and update the guide for the benefit of future readers and others in the community.'' ==Building a cross-compiling libgccjit.so for rustc_codegen_gcc== Before we can use rustc_codegen_gcc, we must compile <code>libgccjit.so</code>, the libgccjit library, for your system. This entails building a unique copy of the SH4 toolchain in its own directory under <code>/opt/toolchains/dc/rust</code>, using a forked version of GCC with enhancements made to libgccjit. The forked version is based on the latest GCC 14.0.1 development branch. * '''NOTE''': This forked version of GCC 14.0.1 with libgccjit changes is actively developed alongside rustc_codegen_gcc itself, so if you update your rustc_codegen_gcc installation later, you may also need to rebuild libgccjit to pull down new changes rustc_codegen_gcc depends upon as well. We will first clone the Rust-for-Dreamcast repository, which contains various supporting files needed to create Rust support for Dreamcast. Using <code>git</code>, clone the repository to <code>/opt/toolchains/dc/rust</code>: git clone https://github.com/darcagn/rust-for-dreamcast /opt/toolchains/dc/rust Enter your KallistiOS installation's <code>dc-chain</code> directory: cd /opt/toolchains/dc/kos/utils/dc-chain Clear out any existing build files: make clean-keep-archives Copy the necessary toolchain patches to your <code>dc-chain</code> setup: cp /opt/toolchains/dc/rust/toolchain/*.diff patches/ Copy the rustc_codegen_gcc toolchain configuration file into place: cp /opt/toolchains/dc/rust/toolchain/config.mk.rustc.sample config.mk Make any desired changes to this <code>config.mk</code> configuration file (e.g., change <code>makejobs=-j2</code> to the number of CPU threads you'd like to use during compilation), and then compile the SH4 toolchain: make build-sh4 When this command is completed successfully, a new SH4 cross-compiler toolchain will exist at <code>/opt/toolchains/dc/rust/sh-elf</code> and your <code>libgccjit.so</code> will be installed to <code>/opt/toolchains/dc/rust/sh-elf/lib/libgccjit.so</code>. ==Building rustc_codegen_gcc== Now that we have libgccjit built, we can use rustc_codegen_gcc to interface with it to generate SuperH machine code from Rust. Clone the rustc_codegen_gcc repository to your rust directory: git clone https://github.com/rust-lang/rustc_codegen_gcc.git /opt/toolchains/dc/rust/rustc_codegen_gcc rustc_codegen_gcc needs a <code>config.toml</code> file that specifies the location of <code>libgccjit.so</code>. Let's write the the <code>gcc-path</code> to the location of our <code>libgccjit.so</code> library file in this file: echo 'gcc-path = "/opt/toolchains/dc/rust/sh-elf/lib"' > /opt/toolchains/dc/rust/rustc_codegen_gcc/config.toml The Rust-for-Dreamcast repository contains scripts and wrappers to assist you in building rustc_codegen_gcc and using it in conjunction with <code>cargo</code> and <code>rustc</code>. You'll need to add the path to those scripts to your <code>PATH</code> environment variable: export PATH="/opt/toolchains/dc/rust/bin:$PATH" You may also want to add the above line to your shell's startup file or else you'll need to re-run it every time you start a new shell. Now we can use the included Rust-for-Dreamcast scripts to set up rustc_codegen_gcc. Patches need to be applied to rustc_codegen_gcc for it to compile properly for our target platform. Let's apply them: rcg-dc patch Now we can prepare and build rustc_codegen_gcc! rcg-dc prepare rcg-dc build =Using Rust for Dreamcast= If all went well, rustc_codegen_gcc will have built successfully. You can now use the scripts included in the Rust for Dreamcast repo: * the <code>rcg-dc</code> script can be used to rebuild the rustc_codegen_gcc code after updating or editing it * the <code>rustc-dc</code> script can be used to compile Rust modules * the <code>cargo-dc</code> script can be used to build Rust crates Examples are included with the Rust for Dreamcast repo to help you get started: * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] demonstrates how to create a simple "Hello, world!" application with KallistiOS using <code>cargo</code> * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] demonstrates a Rust project using KallistiOS with GLdc * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] demonstrates how to create a Rust library that can be included with a KallistiOS project * [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] demonstrates how to compile and include a Rust module into a standard KallistiOS <code>Makefile</code>-based project ==Creating a new Rust project with Cargo== First, we'll demonstrate creating a new "Hello, world!" project with <code>cargo-dc</code>. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-hello <code>cargo-hello</code>] example included in the Rust-for-Dreamcast repo. The Cargo-based examples rely on the [https://github.com/darcagn/kos-rs '''kos-rs'''] crate being present on your computer locally. This is in a separate repo, so let's pull it down now: git clone https://github.com/darcagn/kos-rs /opt/toolchains/dc/rust/kos-rs In a directory of your choosing, let's invoke <code>cargo-dc</code> to create a new project and then enter the directory: cargo-dc new hello cd hello Let's add our kos-rs crate to gain access to current KallistiOS bindings. Open <code>Cargo.toml</code> in your text editor and add: <syntaxhighlight lang="toml"> [dependencies] kos = { package = "kos-rs", path = "/opt/toolchains/dc/rust/kos-rs" } </syntaxhighlight> Now we can open up <code>src/main.rs</code> and write our "Hello, world!" example code: <syntaxhighlight lang="rust" line> #![no_std] #![no_main] extern crate alloc; use kos::println; #[no_mangle] fn main(_argc: isize, _argv: *const *const u8) -> isize { println!("Hello, world!"); return 0; } </syntaxhighlight> * <syntaxhighlight lang="rust" inline>#![no_std]</syntaxhighlight> and <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> tell Rust that our project does not use the standard library and we will not have Rust use a <code>main</code> function as an entry point -- this will be handled by KallistiOS. * <syntaxhighlight lang="rust" inline>extern crate alloc;</syntaxhighlight> tells Rust to use the alloc crate to gain access to heap-allocated types (in our case, <code>String</code>). * <syntaxhighlight lang="rust" inline>use kos::println!;</syntaxhighlight> tells Rust to use the <code>println!</code> macro defined in the kos-rs crate. With this, we can print output to our <code>dc-tool</code> console. * <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> tells Rust to disable name mangling so that the <code>main</code> function can be used by KallistiOS. * Finally, we have a <syntaxhighlight lang="rust" inline>fn main</syntaxhighlight> with the function signature of a typical C <code>main</code> function, containing a basic "Hello, world!" exclamation. Now we can use <code>cargo-dc build</code> to build our project. If all goes well, there will be a <code>target/sh-elf/debug/hello.elf</code> file that can be sent to the Dreamcast with <code>dc-tool</code>. If you have <code>KOS_LOADER</code> set in your KallistiOS environment, you can invoke it directly with <code>cargo-dc run</code>. ==Creating a Rust project using kos-ports libraries== [[File:Rust-Cube rustc codegen-gcc demo.gif|thumb|cube example in action]] The [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-cube <code>cargo-cube</code>] example included in the Rust-for-Dreamcast repo demonstrates creating a rotating 3D cube using Rust as the primary language, while calling C functions provided by the '''GLdc''' library available in kos-ports. This project's initial setup is done the same as the above <code>cargo-hello</code> example. '' '''NOTE''': If you already had GLdc built, make sure you pull the latest GLdc and rebuild with <code>-m4-single</code> -- a very recently fixed bug prevented this demo from working properly under <code>-m4-single</code>.'' We'll be using the GLdc graphics and libm math libraries, so we need to tell <code>cargo-dc</code> to link them in. To do this, we'll add a <code>build.rs</code> file to the root of the crate with the following code: <syntaxhighlight lang="rust"> fn main() { println!("cargo:rustc-link-lib=GL"); println!("cargo:rustc-link-lib=m"); } </syntaxhighlight> We don't need to add the paths to these libraries, because adding the common paths to KallistiOS libraries is already done for us in the kos-rs crate. However, if in your project you need to include a separate unique library path, you can do that like so: <syntaxhighlight lang="rust"> println!("cargo:rustc-link-search=native={}", lib_path); </syntaxhighlight> While not shown here, in the example our <code>build.rs</code> also demonstrates how to use a build script to convert JPG images to VQ-compressed textures with the <code>vqenc</code> tool included with KallistiOS. These texture files are then included in our project using the <syntaxhighlight lang="rust" inline>include_bytes!</syntaxhighlight> macro. The workings of this example's source code are too great to detail here line-by-line, but the example demonstrates declaring and binding external C functions, constants, and structures and then using them in Rust code. Since the entirety of the example is C interop, the <code>main()</code> source is wrapped in <code>unsafe {}</code>. In the future, this would be much less necessary as higher level safe Rust bindings to KallistiOS and other libraries become mature. ==Creating a Rust library== Next, we'll demonstrate creating a Rust library with <code>cargo-dc</code> that can be included in other Dreamcast code. This will follow the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/cargo-addlib <code>cargo-addlib</code>] example included in the Rust-for-Dreamcast repo. Once again, this project's initial setup is done the same as the above <code>cargo-hello</code> example, but you'll create the new project using <code>cargo-dc new --lib addlib</code> to specify that we're creating a library named <code>addlib</code>. You'll also need to add the following text to this project's <code>Cargo.toml</code> file: <syntaxhighlight lang="toml"> [lib] crate-type = ["staticlib"] </syntaxhighlight> This tells Rust to build a static <code>.a</code> library archive file from our code, which is located in <code>src/lib.rs</code>: <syntaxhighlight lang="rust" line> #![no_std] extern crate alloc; use kos::print; #[no_mangle] pub extern "C" fn print_added(a: isize, b: isize) { print!("{}", a + b); } #[no_mangle] pub extern "C" fn add_integers(a: isize, b: isize) -> isize { a + b } </syntaxhighlight> The source code here starts similarly to the "Hello, world!" example, except we don't need to specify <syntaxhighlight lang="rust" inline>#![no_main]</syntaxhighlight> as this is a library which wouldn't have a <code>main()</code> function anyway. Two simple functions are provided: one for adding two integers and returning the result, and another for adding two integers and printing the result as text. Because these functions use <syntaxhighlight lang="rust" inline>#[no_mangle]</syntaxhighlight> and are declared <syntaxhighlight lang="rust" inline>extern "C"</syntaxhighlight>, they can be called by name in C code that links this library. When built using <code>cargo-dc build</code>, a <code>target/sh-elf/debug/libaddlib.a</code> file will be generated. This can be linked into other projects to gain the use of these functions. For example, this can be added to a standard <code>Makefile</code>-based KallistiOS project by editing the <code>Makefile</code>: <syntaxhighlight lang="make"> $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -L/opt/toolchains/dc/rust/examples/cargo-addlib/target/sh-elf/debug -laddlib </syntaxhighlight> Then, we can use the code in our C source: <syntaxhighlight lang="c"> /* Declare the external function from the Rust library */ int add_integers(int a, int b); /* Use the function */ printf("Five plus six is %d\n", add_integers(5, 6)); </syntaxhighlight> ==Compiling individual modules into object files with rustc== If we'd like to mix C and Rust code in the same <code>Makefile</code>-based KallistiOS project without building an entirely separate library, we can do that as well. This is demonstrated in the [https://github.com/darcagn/rust-for-dreamcast/tree/master/examples/rustc-hello <code>rustc-hello</code>] example included in the Rust-for-Dreamcast repo. Instead of using <code>cargo-dc</code>, we can invoke the <code>rustc-dc</code> script in our <code>Makefile</code> to build Rust modules. If we assume the Rust module file is named <code>example.rs</code>, you'll need to add <code>example.o</code> as an object file in your <code>Makefile</code>'s <code>OBJS =</code> declaration. For example, if the project has two source files <code>hello_c.c</code> and <code>hello_rust.rs</code>, our <code>Makefile</code> would have a line like this: <syntaxhighlight lang="make"> OBJS = hello_c.o hello_rust.o </syntaxhighlight> Additionally, you'll need to add the following lines so that <code>make</code> knows how to compile Rust modules into <code>.o</code> object files: <syntaxhighlight lang="make"> %.o: %.rs rustc-dc $< -o $@ </syntaxhighlight> The example code demonstrates starting a C <code>main()</code> function to call a Rust function which builds a <code>String</code> containing the "Hello, world!" text which is passed back to a C function which prints <code>String</code>s. ==Adjusting build settings== Build settings can be adjusted through the <code>CG_GCCFLAGS</code> and <code>CG_RUSTFLAGS</code> environment variables. For example, invoking cargo like so: CG_GCCFLAGS="-freorder-blocks-algorithm=simple" cargo-dc build will build the project while passing along the <code>-freorder-blocks-algorithm=simple</code> optimization setting to the GCC backend. <code>rustc-dc</code> will also pass through these settings. If you wish to adjust the default flags passed to GCC, they are specified in the <code>common.sh</code> file. If you wish to have <code>cargo-dc</code> pass through <code>RUSTFLAGS</code> arguments to the <code>rustc</code> compiler frontend, you can do so by using the <code>CG_RUSTFLAGS</code> environment variable. 19f5e249e8e02fc5eba1cd1bd51dee2162c4a3de Programming language support 0 1429 3501 3348 2024-02-24T18:36:51Z Darc 1 /* Compiled languages */ wikitext text/x-wiki The following languages can be used in Sega Dreamcast programming: =Assembly languages= * '''SH4 assembly''', as the native machine code for the Dreamcast's SuperH processor * '''ARM assembly''', as the native machine code for the Dreamcast's AICA ARM7DI sound processor =Compiled languages= * '''C''', the predominant language for Sega Dreamcast development, via the GCC C compiler. * '''C++''', commonly used and very well-supported, via the GCC C++ compiler. * '''Objective-C''', via the GCC Objective-C compiler. Preliminary support for Foundation framework via [https://gnustep.github.io/ GNUstep] is being developed. See [https://twitter.com/dinobj_c/status/1732399498977276154 Andrew Apperley's X account]. ** The GNU '''Objective-C++''' extension is available as well. * '''Rust''', via rustc_codegen_gcc and libgccjit, or via gccrs. When using rustc_codegen_gcc, the core and alloc libraries are available, with bindings to KallistiOS being developed. See [[Rust on Dreamcast]] for more information. * '''D''', via the GCC D compiler. Early support, see [https://twitter.com/lunafoxgirlvt/status/1736444629149487494 Luna's X account]. * '''Ada''', via GNAT. [https://github.com/dkm/ada-dreamcast-helloworld Ada 3D cube demo] by [https://poulhies.fr/ Marc Poulhiès]. * '''Fortran''', via GFortran. Requires some work to create a cross-compiler, but does work. =Scripting/Interpreted languages= * Lua (available in [[kos-ports]]) * MicroPython (available in [[kos-ports]]) * Tcl (available in [[kos-ports]]) * mRuby (available in [[kos-ports]]) * AngelScript * QuickJS 51fa80595b20923fe62a17989dabd8597d0b5323 Maple bus 0 113 3503 3411 2024-03-10T19:47:51Z Tails86 160 /* Light Gun CRT Beam Detection Sequence */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements both Controller and either Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan either only odd lines or the entire screen, depending on how the specific game is coded. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 16.68 for half or 33.37 milliseconds for full. If no beam is detected, meaning SDCKB remains HIGH throughout the entire period, then the game normally treats this as a gun reload event. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> 239c716596ff9138e665c782835ae306decf3010 3504 3503 2024-03-10T22:56:20Z Tails86 160 /* Light Gun CRT Beam Detection Sequence */ wikitext text/x-wiki The Maple bus is the communications bus the Dreamcast uses to connect controllers and other related peripherals. It is a symmetrical serial protocol. == Hardware Overview == [[File:Dreamcast Port.png|thumb|Dreamcast Port]] Four separate Maple Buses exist on a Dreamcast system - one for each player. Each Maple Bus consists of 2 signal/clock lines that are labeled SDCKA and SDCKB. Hardware on the Maple Bus consists of one host, zero or one main peripheral, and zero to five sub-peripherals. The only difference between a main peripheral and a sub-peripheral is that a main peripheral communicates to the host what sub-peripherals are attached during normal communication. The main peripheral is something like a Dreamcast controller, and the sub-peripherals are things like a VMU, jump pack, and microphone. The host and all connected peripheral devices communicate on the same 2-line Maple Bus.<ref name="MBNutshell">''[https://tech-en.netlify.app/articles/en540236/index.html] Geek Tech Report | Maple BUS in a nutshell or SEGA Dreamcast Peripherals how to make''</ref> Devices are powered with 5V from the host, and signals on the Maple Bus operate at 3.3V TTL.<ref name="raphnet">''[https://www.raphnet.net/programmation/dreamcast_usb/index_en.php] Raphaël Assenat | Dreamcast controller to USB build log''</ref> [[File:Maple Bus Electronics Block Diagram.png|frameless|500px|Maple Bus Electronics Block Diagram]] * Both lines on the Bus are pulled HIGH through weak pullup resistors * Only one connected component on the bus may communicate at a time * During communication, a device should not drive both lines HIGH for very long to prevent a downstream device from thinking the bus is free * Before a component starts communicating, it must verify the bus is neutral for a sufficient amount of time * A peripheral device will only communicate 1 packet of data in response to a request from the host<ref name="MBNutshell" /> [[File:Maple Bus Hardware Communication.png|frameless|600px|Maple Bus Hardware Communication]] === Sense === The Dreamcast does not rely on any sense line as some projects implement.<ref name="raphnet" /><ref>''[http://mc.pp.se/dc/controller.html] Dreamcast Programming - Controllers''</ref><ref>''[https://hackaday.com/2021/03/16/dreamcast-controller-adapter-even-works-with-mice/] Lewin Day | DREAMCAST CONTROLLER ADAPTER EVEN WORKS WITH MICE''</ref> Both ground wires from the controller are tied to ground at the controller port module on the Dreamcast. To detect the presence of a device, Dreamcast instead sends a device info request every 16 ms until a main peripheral responds on the bus. == Maple Bus Signals == There is no handshaking done to determine how fast each component may transmit on the Maple Bus. Transmission speeds are internally pre-determined by each hardware component. Generally speaking, for all signals, the minimum amount of time between an edge (transition between logic levels) of one line and an edge of the other is about 125 nanoseconds. The minimum amount of time between edges on the same line is about 225 nanoseconds.<ref name="MBMeasurements">''[https://github.com/OrangeFox86/DreamcastControllerUsbPico/tree/main/measurements] Tails86 | DreamcastControllerUsbPico Maple Bus Measurements''</ref> There is no maximum time limit as long as both lines aren't held HIGH during active transmission for any extended amount of time. These guidelines may be applied for any sequence below. === Data Packet Start Sequence === [[File:Maple Bus Start Sequence.png|thumb|Maple Bus Start Sequence]] Every data packet begins with a start sequence. # SDCKA is brought LOW # SDCKB is toggled 4 times # SDCKA is then brought back HIGH to complete the sequence<ref name="MBWireProtocol">''[http://mc.pp.se/dc/maplewire.html] Marcus Comstedt | Dreamcast Programming - Maple Bus Wire Protocol''</ref> <br> === Data Packet End Sequence === [[File:Maple Bus End Sequence.png|thumb|Maple Bus End Sequence]] Every packet is completed with an end sequence to commit the data to the target component. # SDCKA is brought HIGH # SDCKB is toggled HIGH then LOW # SDCKA is toggled 2 times # SDCKB is brought back HIGH to complete the sequence<ref name="MBWireProtocol"/> <br><br><br><br><br><br> === Data Bit Sequences === [[File:Maple Bus Clocking Phases.png|thumb|Maple Bus Clocking Phases]] For each bit, one line of the maple bus acts as a clock while the other is the data to be sampled. A data bit is clocked when the designated clock line transitions from HIGH to LOW. The two lines trade their function after each bit. Line '''A''' acts as clock and '''B''' acts as data for the first bit. Line '''B''' acts as clock and '''A''' acts as data for the next bit. Line '''A''' acts as clock again for the bit after that. The pattern repeats until all data is transmitted. Each bit transmission sequence can be broken down into 3 phases<ref>''[https://archive.org/details/MaplePatent/mode/1up]Maple Bus Patent''</ref>: * Phase 1 - Clock Conditioning: Bring clock HIGH and keep data at the state it was previously * Phase 2 - Data Conditioning: Transition the data bit to the target value * Phase 3 - Clocking: Bring clock LOW in order to have the data bit sampled There are a total of 6 types of state transitions, depending on what the previous phase was and the target bit value. A depiction of state transitions can be seen in the image below. [[File:Maple Bus Data.png|Maple Bus Data]] Notice that each line, A & B transitions states in a staggard pattern i.e., only one line may change its logic level within each phase. Because of the staggard pattern, the minimum time between an edge of one line and an edge of the other is 1 phase length, and the minimum time between edges on the same line is the sum of the time of 2 phases. The total bit transmission time is of course the sum of the time of all 3 phases. * The Dreamcast host transmits each phase at about 160 nanoseconds<ref name="MBMeasurements" /> ** This works out to be about 2 mbps raw data transfer speed * Dreamcast controllers and other peripheral devices usually transmit a little slower at about 250 nanoseconds per phase and sometimes with about 110 to 130 microsecond delays between each 4-word chunk after the first frame word<ref name="MBMeasurements" /> ** This works out to between about 0.5 and 1.3 mbps raw data transfer speed === Light Gun CRT Beam Detection Sequence === The start sequence for light gun CRT beam detection looks similar to a data packet start sequence, but 8 pulses on the SDCKB line signify the start of this mode. This mode is used to gain precise timing for position detection of the electron beam for a specific pixel on a CRT monitor which the light gun is currently aiming at. This mode is only activated when the main peripheral implements both Controller and either Gun or AR Gun [[Maple_bus#Function_Codes|function code]]. Dreamcast initiates this sequence to a light gun once the Dreamcast detects that the trigger (A button) has been pressed through normal data packet sequences. The light gun is expected to bring SDCKB LOW within the period of time marked blue in the image below once it detects that the electron beam of a CRT is in view of the light gun's lens. Once the Dreamcast brings SDCKA back HIGH, SDCKB must be brought back HIGH, and the control of SDCKB must be let go by the light gun. No end sequence is sent after this is completed. The duration of time given for beam detection is the time it takes to scan either only odd lines or the entire screen, depending on how the specific game is coded. For a 60 Hz screen (59.94 Hz actual) displaying 480i, this is about 16.68 milliseconds for half or 33.37 milliseconds for full. If no beam is detected, meaning SDCKB remains HIGH throughout the entire period, then the game normally treats this as a gun reload event. [[File:Light Gun CRT Beam Detect.png|Light Gun CRT Beam Detect]] === Reset Sequence === A reset sequence may be sent from the host in order to attempt to reset all devices on the bus. It is similar to a start sequence, but there are 14 pulses on SDCKB. [[File:Maple Bus Reset Sequence.png|Maple Bus Reset Sequence]] == Maple Bus Data Packet == This section contains information about the packet structure inherent to the Maple Bus. Any data transmission follows this packet structure. === Word Format === Each word is 32 bits in length, transmitted in little-endian byte order. The most significant bit of each byte transmits first. This means that the most significant bit of the least significant byte of each word transmits first. All tables in this wiki list bytes in transmission order with the least significant bit (LSB) as the first byte. When ASCII text or a byte stream is transmitted, the most significant byte is the first character of the 4 character sequence in each word. This means that the byte order of each word needs to be flipped before parsing the payload as a character or byte array. The size of an ASCII payload section is pre-determined based on the command. No NULL termination byte is supplied at the end of the string, and spaces (0x20) are used to pad out remaining characters at the end of the string. === Packet Data Format === A packet consists of the following data. * '''[[Maple_bus#Frame_Word|Frame]]:''' 1 32-Bit Word * '''[[Maple_bus#Payload|Payload]]:''' 0 to 255 32-Bit Words * '''[[Maple_bus#CRC|CRC]]:''' 1 Byte ==== Frame Word ==== The following is how a frame word is broken down into its 4 parts<ref name="DPMapleBus">''[http://mc.pp.se/dc/maplebus.html] Marcus Comstedt | Dreamcast Programming - Maple Bus''</ref>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | <div style="text-align: center;">Number of Words<br>in Payload</div> || <div style="text-align: center;">Sender<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">Recipient<br>[[Maple_bus#Addressing|Address]]</div> || <div style="text-align: center;">[[Maple_bus#Commands|Command]]</div> |} example: [[File:Frame Word.png|Frame Word Example]] ===== Addressing ===== The following addresses are used for all components on the bus. {| class="wikitable" |- ! Player Number !! Host !! Main Peripheral !! Sub-Peripheral 1 !! Sub-Peripheral 2 !! Sub-Peripheral 3 !! Sub-Peripheral 4 !! Sub-Peripheral 5 |- | 1 || 0x00 || 0x20* || 0x01 || 0x02 || 0x04 || 0x08 || 0x10 |- | 2 || 0x40 || 0x60* || 0x41 || 0x42 || 0x44 || 0x48 || 0x50 |- | 3 || 0x80 || 0xA0* || 0x81 || 0x82 || 0x84 || 0x88 || 0x90 |- | 4 || 0xC0 || 0xE0* || 0xC1 || 0xC2 || 0xC4 || 0xC8 || 0xD0 |} <nowiki>*</nowiki>When the main peripheral responds with its sender address, it also sets the bits corresponding to which sub-peripherals are attached. For example, if sub-peripherals 1 and 2 are attached to player 1's main peripheral, the main peripheral will set its sender address to 0x23. This informs the host what else is attached. The host should still set the recipient address to 0x20 when sending data to this peripheral though. In testing, there have been cases where a peripheral will respond with a sender address as if it is player 1. As such, the host should ignore whatever the upper 2 bits that the device uses as its sender address. ===== Commands ===== Below shows command values and their meanings.<ref name="DPMapleBus"/><ref name="DCDocs">''[https://github.com/Kochise/dreamcast-docs/tree/master/CONTROLR/DOCS] Dreamcast Documents''</ref> For the communication direction, Host implies the Dreamcast and Device implies a peripheral. {| class="wikitable" |- ! Command Value !! Description !! Communication Direction !! Number of Payload Words !! Expected Response** |- | 0x01 || Device Info Request* || Host->Device || 0 || 0x05 |- | 0x02 || Extended Device Info Request || Host->Device || 0 || 0x06 |- | 0x03 || Reset || Host->Device || 0 || 0x07 |- | 0x04 || Shutdown || Host->Device || 0 || 0x07 |- | 0x05 || Device Info || Device->Host || [[Maple_bus#Device_Info_Payload_Structure_.28cmd_0x05.29|28]] || - |- | 0x06 || Extended Device Info || Device->Host || [[Maple_bus#Extended_Device_Info_Payload_Structure_.28cmd_0x06.29|48]] || - |- | 0x07 || Acknowledge || Device->Host || 0 || - |- | 0x08 || Data Transfer || Device->Host || [[Maple_bus#Data_Transfer_Payload_Structure_.28cmd_0x08.29|2..255]] || - |- | 0x09 || Get Condition || Host->Device || [[Maple_bus#Get_Condition_Payload_Structure_.28cmd_0x09.29|1]] || 0x08 |- | 0x0A || Get Memory Information || Host->Device || [[Maple_bus#Get_Memory_Information_Payload_Structure_.28cmd_0x0A.29|2]] || 0x08 |- | 0x0B || Block Read || Host->Device || [[Maple_bus#Block_Read_Payload_Structure_.28cmd_0x0B.29|2]] || 0x08 |- | 0x0C || Block Write || Host->Device || [[Maple_bus#Block_Write_Payload_Structure_.28cmd_0x0C.29|3..255]] || 0x07 |- | 0x0D || Get Last Error || Host->Device || [[Maple_bus#Get_Last_Error_Payload_Structure_.28cmd_0x0D.29|2]] || 0x07 |- | 0x0E || Set Condition || Host->Device || [[Maple_bus#Set_Condition_Payload_Structure_.28cmd_0x0E.29|2..255]] || 0x07 |- | 0xF9 || AR Error || Device->Host || 0 || - |- | 0xFA || LCD Error || Device->Host || 0 || - |- | 0xFB || File Error || Device->Host || 0 || - |- | 0xFC || Request Resend || ANY || 0 || Last Sent Command |- | 0xFD || Unknown Command || Device->Host || 0 || - |- | 0xFE || [[Maple_bus#Function_Codes|Function code]] Not Supported || Device->Host || 0 || - |} <nowiki>*</nowiki>Most peripheral devices won't respond to any other command until device info is requested for the device. <nowiki>**</nowiki>This is the expected response when device didn't experience an error ==== Payload ==== The structure of a payload is dependent on the command used in the frame word. ===== Device Info Payload Structure (cmd 0x05) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Extended Device Info Payload Structure (cmd 0x06) ===== {| class="wikitable" |- ! Word 0 !! Words 1-3 !! Word 4 !! Words 5-11 !! Words 12-26 !! Word 27 !! Words 28-47 |- | Supported [[Maple_bus#Function_Codes|function codes]] mask* || Function definitions for up to 3 devices** || Byte 3 (MSB): Region code <br> Byte 2: Connection direction code <br> Bytes 1 and 0: first two characters of description ASCII string*** || The rest of the description ASCII string*** || Producer information ASCII string*** || 2 most significant bytes: standby current consumption <br> 2 least significant bytes: maximum current consumption**** || Version information and/or capabilities ASCII string*** |} <nowiki>*</nowiki>The supported function codes mask in device info responses will contain the bitmask for 1 or more devices ex: a VMU will have a mask of 0x0000000E for Timer, Screen, and Storage. <nowiki>**</nowiki>The first word in this set is meant for the most significant bit that is set to 1 in the function codes word <nowiki>***</nowiki>Refer to the [[Maple_bus#Word_Format|word format]] section about how to parse ASCII strings. <nowiki>****</nowiki>Current values in (x / 10) mA, each two byte value is transmitted as big-endian ===== Data Transfer Payload Structure (cmd 0x08) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Data - device dependent structure |} ===== Get Condition Payload Structure (cmd 0x09) ===== {| class="wikitable" |- ! Word 0 |- | [[Maple_bus#Function_Codes|Function code]] |} ===== Get Memory Information Payload Structure (cmd 0x0A) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]]* |} <nowiki>*</nowiki>Only the partition number should be set in the location word. Set all other bytes in the location word to 0. ===== Block Read Payload Structure (cmd 0x0B) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Block Write Payload Structure (cmd 0x0C) ===== {| class="wikitable" |- ! Word 0 !! Word 1 !! Words 2..255 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] || Data - device dependent structure |} ===== Get Last Error Payload Structure (cmd 0x0D) ===== {| class="wikitable" |- ! Word 0 !! Word 1 |- | [[Maple_bus#Function_Codes|Function code]] || [[Maple_bus#Location_Word|Location word]] |} ===== Set Condition Payload Structure (cmd 0x0E) ===== {| class="wikitable" |- ! Word 0 !! Words 1..255 |- | [[Maple_bus#Function_Codes|Function code]] || Condition - device dependent structure |} ===== Common Payload Word Types ===== The following word types are used in some of the above payload structures. ====== Function Codes ====== The below are function codes which are used to address functionality in some payloads<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Code / Mask !! Description |- | 0x00000001 || Controller |- | 0x00000002 || Storage |- | 0x00000004 || Screen |- | 0x00000008 || Timer |- | 0x00000010 || Audio Input |- | 0x00000020 || AR Gun |- | 0x00000040 || Keyboard |- | 0x00000080 || Gun |- | 0x00000100 || Vibration |- | 0x00000200 || Mouse |} ====== Location Word ====== Below defines a location word which is used to address blocks of memory in some peripherals<ref name="DPMapleBus"/>. {| class="wikitable" |- ! Byte 0 (LSB) !! Byte 1 !! Byte 2 !! Byte 3 (MSB) |- | Block LSB || Block MSB || Phase || Partition |} * '''Block''': Memory block number index * '''Phase''': Sequence number (starts at 0 and counts up) * '''Partition''': Partition number (normally 0) ==== CRC ==== CRC byte transmits last, just before the end sequence is transmitted. It is the value after starting with 0 and applying XOR against each byte in the packet. == Peripheral Implementation == Refer to the following pages for a specific peripheral implementation. * [[Controller peripheral]] * [[VMU peripheral]] * [[Jump pack peripheral]] == References == <references /> 8236ba6b4528272663140f75426e44baa8aed1cb